diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-29 14:32:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-29 14:32:34 -0400 |
commit | 3aa590c6b7c89d844f81c2e96f295cf2c6967773 (patch) | |
tree | 6f18b295b1ff4cd7fd1880db6f56721599d64439 /arch/powerpc/kernel | |
parent | 4d3ce21fa9d2eaeda113aa2f9c2da80d972bef64 (diff) | |
parent | 339d76c54336443f5050b00172beb675f35e3be0 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (43 commits)
[POWERPC] Use little-endian bit from firmware ibm,pa-features property
[POWERPC] Make sure smp_processor_id works very early in boot
[POWERPC] U4 DART improvements
[POWERPC] todc: add support for Time-Of-Day-Clock
[POWERPC] Make lparcfg.c work when both iseries and pseries are selected
[POWERPC] Fix idr locking in init_new_context
[POWERPC] mpc7448hpc2 (taiga) board config file
[POWERPC] Add tsi108 pci and platform device data register function
[POWERPC] Add general support for mpc7448hpc2 (Taiga) platform
[POWERPC] Correct the MAX_CONTEXT definition
powerpc: minor cleanups for mpc86xx
[POWERPC] Make sure we select CONFIG_NEW_LEDS if ADB_PMU_LED is set
[POWERPC] Simplify the code defining the 64-bit CPU features
[POWERPC] powerpc: kconfig warning fix
[POWERPC] Consolidate some of kernel/misc*.S
[POWERPC] Remove unused function call_with_mmu_off
[POWERPC] update asm-powerpc/time.h
[POWERPC] Clean up it_lp_queue.h
[POWERPC] Skip the "copy down" of the kernel if it is already at zero.
[POWERPC] Add the use of the firmware soft-reset-nmi to kdump.
...
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/Makefile | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/cpu_setup_power4.S | 14 | ||||
-rw-r--r-- | arch/powerpc/kernel/cputable.c | 12 | ||||
-rw-r--r-- | arch/powerpc/kernel/crash.c | 147 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 62 | ||||
-rw-r--r-- | arch/powerpc/kernel/iommu.c | 30 | ||||
-rw-r--r-- | arch/powerpc/kernel/legacy_serial.c | 11 | ||||
-rw-r--r-- | arch/powerpc/kernel/lparcfg.c | 147 | ||||
-rw-r--r-- | arch/powerpc/kernel/machine_kexec_64.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/misc.S | 203 | ||||
-rw-r--r-- | arch/powerpc/kernel/misc_32.S | 156 | ||||
-rw-r--r-- | arch/powerpc/kernel/misc_64.S | 223 | ||||
-rw-r--r-- | arch/powerpc/kernel/paca.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom.c | 49 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtas.c | 119 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_64.c | 22 | ||||
-rw-r--r-- | arch/powerpc/kernel/traps.c | 27 | ||||
-rw-r--r-- | arch/powerpc/kernel/udbg.c | 7 |
18 files changed, 638 insertions, 599 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 803858e86160..814f242aeb8c 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -50,7 +50,8 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o | |||
50 | extra-$(CONFIG_8xx) := head_8xx.o | 50 | extra-$(CONFIG_8xx) := head_8xx.o |
51 | extra-y += vmlinux.lds | 51 | extra-y += vmlinux.lds |
52 | 52 | ||
53 | obj-y += time.o prom.o traps.o setup-common.o udbg.o | 53 | obj-y += time.o prom.o traps.o setup-common.o \ |
54 | udbg.o misc.o | ||
54 | obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o | 55 | obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o |
55 | obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o | 56 | obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o |
56 | obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o | 57 | obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o |
diff --git a/arch/powerpc/kernel/cpu_setup_power4.S b/arch/powerpc/kernel/cpu_setup_power4.S index 271418308d53..1fc863261003 100644 --- a/arch/powerpc/kernel/cpu_setup_power4.S +++ b/arch/powerpc/kernel/cpu_setup_power4.S | |||
@@ -125,7 +125,12 @@ _GLOBAL(__save_cpu_setup) | |||
125 | cmpwi r0,0x44 | 125 | cmpwi r0,0x44 |
126 | bne 2f | 126 | bne 2f |
127 | 127 | ||
128 | 1: /* Save HID0,1,4 and 5 */ | 128 | 1: /* skip if not running in HV mode */ |
129 | mfmsr r0 | ||
130 | rldicl. r0,r0,4,63 | ||
131 | beq 2f | ||
132 | |||
133 | /* Save HID0,1,4 and 5 */ | ||
129 | mfspr r3,SPRN_HID0 | 134 | mfspr r3,SPRN_HID0 |
130 | std r3,CS_HID0(r5) | 135 | std r3,CS_HID0(r5) |
131 | mfspr r3,SPRN_HID1 | 136 | mfspr r3,SPRN_HID1 |
@@ -159,7 +164,12 @@ _GLOBAL(__restore_cpu_setup) | |||
159 | cmpwi r0,0x44 | 164 | cmpwi r0,0x44 |
160 | bnelr | 165 | bnelr |
161 | 166 | ||
162 | 1: /* Before accessing memory, we make sure rm_ci is clear */ | 167 | 1: /* skip if not running in HV mode */ |
168 | mfmsr r0 | ||
169 | rldicl. r0,r0,4,63 | ||
170 | beqlr | ||
171 | |||
172 | /* Before accessing memory, we make sure rm_ci is clear */ | ||
163 | li r0,0 | 173 | li r0,0 |
164 | mfspr r3,SPRN_HID4 | 174 | mfspr r3,SPRN_HID4 |
165 | rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ | 175 | rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 1c114880dc05..abf7d42a8b07 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -722,18 +722,6 @@ struct cpu_spec cpu_specs[] = { | |||
722 | .oprofile_type = PPC_OPROFILE_G4, | 722 | .oprofile_type = PPC_OPROFILE_G4, |
723 | .platform = "ppc7450", | 723 | .platform = "ppc7450", |
724 | }, | 724 | }, |
725 | { /* 8641 */ | ||
726 | .pvr_mask = 0xffffffff, | ||
727 | .pvr_value = 0x80040010, | ||
728 | .cpu_name = "8641", | ||
729 | .cpu_features = CPU_FTRS_7447A, | ||
730 | .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, | ||
731 | .icache_bsize = 32, | ||
732 | .dcache_bsize = 32, | ||
733 | .num_pmcs = 6, | ||
734 | .cpu_setup = __setup_cpu_745x | ||
735 | }, | ||
736 | |||
737 | { /* 82xx (8240, 8245, 8260 are all 603e cores) */ | 725 | { /* 82xx (8240, 8245, 8260 are all 603e cores) */ |
738 | .pvr_mask = 0x7fff0000, | 726 | .pvr_mask = 0x7fff0000, |
739 | .pvr_value = 0x00810000, | 727 | .pvr_value = 0x00810000, |
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 22ceba844bf4..358cecdc6aef 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c | |||
@@ -24,9 +24,11 @@ | |||
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/irq.h> | 25 | #include <linux/irq.h> |
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <linux/irq.h> | ||
27 | 28 | ||
28 | #include <asm/processor.h> | 29 | #include <asm/processor.h> |
29 | #include <asm/machdep.h> | 30 | #include <asm/machdep.h> |
31 | #include <asm/kexec.h> | ||
30 | #include <asm/kdump.h> | 32 | #include <asm/kdump.h> |
31 | #include <asm/lmb.h> | 33 | #include <asm/lmb.h> |
32 | #include <asm/firmware.h> | 34 | #include <asm/firmware.h> |
@@ -41,6 +43,7 @@ | |||
41 | 43 | ||
42 | /* This keeps a track of which one is crashing cpu. */ | 44 | /* This keeps a track of which one is crashing cpu. */ |
43 | int crashing_cpu = -1; | 45 | int crashing_cpu = -1; |
46 | static cpumask_t cpus_in_crash = CPU_MASK_NONE; | ||
44 | 47 | ||
45 | static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, | 48 | static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, |
46 | size_t data_len) | 49 | size_t data_len) |
@@ -98,34 +101,66 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu) | |||
98 | } | 101 | } |
99 | 102 | ||
100 | #ifdef CONFIG_SMP | 103 | #ifdef CONFIG_SMP |
101 | static atomic_t waiting_for_crash_ipi; | 104 | static atomic_t enter_on_soft_reset = ATOMIC_INIT(0); |
102 | 105 | ||
103 | void crash_ipi_callback(struct pt_regs *regs) | 106 | void crash_ipi_callback(struct pt_regs *regs) |
104 | { | 107 | { |
105 | int cpu = smp_processor_id(); | 108 | int cpu = smp_processor_id(); |
106 | 109 | ||
107 | if (cpu == crashing_cpu) | ||
108 | return; | ||
109 | |||
110 | if (!cpu_online(cpu)) | 110 | if (!cpu_online(cpu)) |
111 | return; | 111 | return; |
112 | 112 | ||
113 | if (ppc_md.kexec_cpu_down) | ||
114 | ppc_md.kexec_cpu_down(1, 1); | ||
115 | |||
116 | local_irq_disable(); | 113 | local_irq_disable(); |
114 | if (!cpu_isset(cpu, cpus_in_crash)) | ||
115 | crash_save_this_cpu(regs, cpu); | ||
116 | cpu_set(cpu, cpus_in_crash); | ||
117 | 117 | ||
118 | crash_save_this_cpu(regs, cpu); | 118 | /* |
119 | atomic_dec(&waiting_for_crash_ipi); | 119 | * Entered via soft-reset - could be the kdump |
120 | * process is invoked using soft-reset or user activated | ||
121 | * it if some CPU did not respond to an IPI. | ||
122 | * For soft-reset, the secondary CPU can enter this func | ||
123 | * twice. 1 - using IPI, and 2. soft-reset. | ||
124 | * Tell the kexec CPU that entered via soft-reset and ready | ||
125 | * to go down. | ||
126 | */ | ||
127 | if (cpu_isset(cpu, cpus_in_sr)) { | ||
128 | cpu_clear(cpu, cpus_in_sr); | ||
129 | atomic_inc(&enter_on_soft_reset); | ||
130 | } | ||
131 | |||
132 | /* | ||
133 | * Starting the kdump boot. | ||
134 | * This barrier is needed to make sure that all CPUs are stopped. | ||
135 | * If not, soft-reset will be invoked to bring other CPUs. | ||
136 | */ | ||
137 | while (!cpu_isset(crashing_cpu, cpus_in_crash)) | ||
138 | cpu_relax(); | ||
139 | |||
140 | if (ppc_md.kexec_cpu_down) | ||
141 | ppc_md.kexec_cpu_down(1, 1); | ||
120 | kexec_smp_wait(); | 142 | kexec_smp_wait(); |
121 | /* NOTREACHED */ | 143 | /* NOTREACHED */ |
122 | } | 144 | } |
123 | 145 | ||
124 | static void crash_kexec_prepare_cpus(void) | 146 | /* |
147 | * Wait until all CPUs are entered via soft-reset. | ||
148 | */ | ||
149 | static void crash_soft_reset_check(int cpu) | ||
150 | { | ||
151 | unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ | ||
152 | |||
153 | cpu_clear(cpu, cpus_in_sr); | ||
154 | while (atomic_read(&enter_on_soft_reset) != ncpus) | ||
155 | cpu_relax(); | ||
156 | } | ||
157 | |||
158 | |||
159 | static void crash_kexec_prepare_cpus(int cpu) | ||
125 | { | 160 | { |
126 | unsigned int msecs; | 161 | unsigned int msecs; |
127 | 162 | ||
128 | atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); | 163 | unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ |
129 | 164 | ||
130 | crash_send_ipi(crash_ipi_callback); | 165 | crash_send_ipi(crash_ipi_callback); |
131 | smp_wmb(); | 166 | smp_wmb(); |
@@ -133,14 +168,13 @@ static void crash_kexec_prepare_cpus(void) | |||
133 | /* | 168 | /* |
134 | * FIXME: Until we will have the way to stop other CPUSs reliabally, | 169 | * FIXME: Until we will have the way to stop other CPUSs reliabally, |
135 | * the crash CPU will send an IPI and wait for other CPUs to | 170 | * the crash CPU will send an IPI and wait for other CPUs to |
136 | * respond. If not, proceed the kexec boot even though we failed to | 171 | * respond. |
137 | * capture other CPU states. | ||
138 | * Delay of at least 10 seconds. | 172 | * Delay of at least 10 seconds. |
139 | */ | 173 | */ |
140 | printk(KERN_ALERT "Sending IPI to other cpus...\n"); | 174 | printk(KERN_EMERG "Sending IPI to other cpus...\n"); |
141 | msecs = 10000; | 175 | msecs = 10000; |
142 | while ((atomic_read(&waiting_for_crash_ipi) > 0) && (--msecs > 0)) { | 176 | while ((cpus_weight(cpus_in_crash) < ncpus) && (--msecs > 0)) { |
143 | barrier(); | 177 | cpu_relax(); |
144 | mdelay(1); | 178 | mdelay(1); |
145 | } | 179 | } |
146 | 180 | ||
@@ -149,18 +183,71 @@ static void crash_kexec_prepare_cpus(void) | |||
149 | /* | 183 | /* |
150 | * FIXME: In case if we do not get all CPUs, one possibility: ask the | 184 | * FIXME: In case if we do not get all CPUs, one possibility: ask the |
151 | * user to do soft reset such that we get all. | 185 | * user to do soft reset such that we get all. |
152 | * IPI handler is already set by the panic cpu initially. Therefore, | 186 | * Soft-reset will be used until better mechanism is implemented. |
153 | * all cpus could invoke this handler from die() and the panic CPU | 187 | */ |
154 | * will call machine_kexec() directly from this handler to do | 188 | if (cpus_weight(cpus_in_crash) < ncpus) { |
155 | * kexec boot. | 189 | printk(KERN_EMERG "done waiting: %d cpu(s) not responding\n", |
190 | ncpus - cpus_weight(cpus_in_crash)); | ||
191 | printk(KERN_EMERG "Activate soft-reset to stop other cpu(s)\n"); | ||
192 | cpus_in_sr = CPU_MASK_NONE; | ||
193 | atomic_set(&enter_on_soft_reset, 0); | ||
194 | while (cpus_weight(cpus_in_crash) < ncpus) | ||
195 | cpu_relax(); | ||
196 | } | ||
197 | /* | ||
198 | * Make sure all CPUs are entered via soft-reset if the kdump is | ||
199 | * invoked using soft-reset. | ||
156 | */ | 200 | */ |
157 | if (atomic_read(&waiting_for_crash_ipi)) | 201 | if (cpu_isset(cpu, cpus_in_sr)) |
158 | printk(KERN_ALERT "done waiting: %d cpus not responding\n", | 202 | crash_soft_reset_check(cpu); |
159 | atomic_read(&waiting_for_crash_ipi)); | ||
160 | /* Leave the IPI callback set */ | 203 | /* Leave the IPI callback set */ |
161 | } | 204 | } |
205 | |||
206 | /* | ||
207 | * This function will be called by secondary cpus or by kexec cpu | ||
208 | * if soft-reset is activated to stop some CPUs. | ||
209 | */ | ||
210 | void crash_kexec_secondary(struct pt_regs *regs) | ||
211 | { | ||
212 | int cpu = smp_processor_id(); | ||
213 | unsigned long flags; | ||
214 | int msecs = 5; | ||
215 | |||
216 | local_irq_save(flags); | ||
217 | /* Wait 5ms if the kexec CPU is not entered yet. */ | ||
218 | while (crashing_cpu < 0) { | ||
219 | if (--msecs < 0) { | ||
220 | /* | ||
221 | * Either kdump image is not loaded or | ||
222 | * kdump process is not started - Probably xmon | ||
223 | * exited using 'x'(exit and recover) or | ||
224 | * kexec_should_crash() failed for all running tasks. | ||
225 | */ | ||
226 | cpu_clear(cpu, cpus_in_sr); | ||
227 | local_irq_restore(flags); | ||
228 | return; | ||
229 | } | ||
230 | mdelay(1); | ||
231 | cpu_relax(); | ||
232 | } | ||
233 | if (cpu == crashing_cpu) { | ||
234 | /* | ||
235 | * Panic CPU will enter this func only via soft-reset. | ||
236 | * Wait until all secondary CPUs entered and | ||
237 | * then start kexec boot. | ||
238 | */ | ||
239 | crash_soft_reset_check(cpu); | ||
240 | cpu_set(crashing_cpu, cpus_in_crash); | ||
241 | if (ppc_md.kexec_cpu_down) | ||
242 | ppc_md.kexec_cpu_down(1, 0); | ||
243 | machine_kexec(kexec_crash_image); | ||
244 | /* NOTREACHED */ | ||
245 | } | ||
246 | crash_ipi_callback(regs); | ||
247 | } | ||
248 | |||
162 | #else | 249 | #else |
163 | static void crash_kexec_prepare_cpus(void) | 250 | static void crash_kexec_prepare_cpus(int cpu) |
164 | { | 251 | { |
165 | /* | 252 | /* |
166 | * move the secondarys to us so that we can copy | 253 | * move the secondarys to us so that we can copy |
@@ -171,6 +258,10 @@ static void crash_kexec_prepare_cpus(void) | |||
171 | smp_release_cpus(); | 258 | smp_release_cpus(); |
172 | } | 259 | } |
173 | 260 | ||
261 | void crash_kexec_secondary(struct pt_regs *regs) | ||
262 | { | ||
263 | cpus_in_sr = CPU_MASK_NONE; | ||
264 | } | ||
174 | #endif | 265 | #endif |
175 | 266 | ||
176 | void default_machine_crash_shutdown(struct pt_regs *regs) | 267 | void default_machine_crash_shutdown(struct pt_regs *regs) |
@@ -199,14 +290,14 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
199 | desc->chip->disable(irq); | 290 | desc->chip->disable(irq); |
200 | } | 291 | } |
201 | 292 | ||
202 | if (ppc_md.kexec_cpu_down) | ||
203 | ppc_md.kexec_cpu_down(1, 0); | ||
204 | |||
205 | /* | 293 | /* |
206 | * Make a note of crashing cpu. Will be used in machine_kexec | 294 | * Make a note of crashing cpu. Will be used in machine_kexec |
207 | * such that another IPI will not be sent. | 295 | * such that another IPI will not be sent. |
208 | */ | 296 | */ |
209 | crashing_cpu = smp_processor_id(); | 297 | crashing_cpu = smp_processor_id(); |
210 | crash_kexec_prepare_cpus(); | ||
211 | crash_save_this_cpu(regs, crashing_cpu); | 298 | crash_save_this_cpu(regs, crashing_cpu); |
299 | crash_kexec_prepare_cpus(crashing_cpu); | ||
300 | cpu_set(crashing_cpu, cpus_in_crash); | ||
301 | if (ppc_md.kexec_cpu_down) | ||
302 | ppc_md.kexec_cpu_down(1, 0); | ||
212 | } | 303 | } |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 831acbdf2592..8cfd040d1f50 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -85,34 +85,6 @@ END_FTR_SECTION(0, 1) | |||
85 | /* Catch branch to 0 in real mode */ | 85 | /* Catch branch to 0 in real mode */ |
86 | trap | 86 | trap |
87 | 87 | ||
88 | #ifdef CONFIG_PPC_ISERIES | ||
89 | /* | ||
90 | * At offset 0x20, there is a pointer to iSeries LPAR data. | ||
91 | * This is required by the hypervisor | ||
92 | */ | ||
93 | . = 0x20 | ||
94 | .llong hvReleaseData-KERNELBASE | ||
95 | |||
96 | /* | ||
97 | * At offset 0x28 and 0x30 are offsets to the mschunks_map | ||
98 | * array (used by the iSeries LPAR debugger to do translation | ||
99 | * between physical addresses and absolute addresses) and | ||
100 | * to the pidhash table (also used by the debugger) | ||
101 | */ | ||
102 | .llong mschunks_map-KERNELBASE | ||
103 | .llong 0 /* pidhash-KERNELBASE SFRXXX */ | ||
104 | |||
105 | /* Offset 0x38 - Pointer to start of embedded System.map */ | ||
106 | .globl embedded_sysmap_start | ||
107 | embedded_sysmap_start: | ||
108 | .llong 0 | ||
109 | /* Offset 0x40 - Pointer to end of embedded System.map */ | ||
110 | .globl embedded_sysmap_end | ||
111 | embedded_sysmap_end: | ||
112 | .llong 0 | ||
113 | |||
114 | #endif /* CONFIG_PPC_ISERIES */ | ||
115 | |||
116 | /* Secondary processors spin on this value until it goes to 1. */ | 88 | /* Secondary processors spin on this value until it goes to 1. */ |
117 | .globl __secondary_hold_spinloop | 89 | .globl __secondary_hold_spinloop |
118 | __secondary_hold_spinloop: | 90 | __secondary_hold_spinloop: |
@@ -124,6 +96,15 @@ __secondary_hold_spinloop: | |||
124 | __secondary_hold_acknowledge: | 96 | __secondary_hold_acknowledge: |
125 | .llong 0x0 | 97 | .llong 0x0 |
126 | 98 | ||
99 | #ifdef CONFIG_PPC_ISERIES | ||
100 | /* | ||
101 | * At offset 0x20, there is a pointer to iSeries LPAR data. | ||
102 | * This is required by the hypervisor | ||
103 | */ | ||
104 | . = 0x20 | ||
105 | .llong hvReleaseData-KERNELBASE | ||
106 | #endif /* CONFIG_PPC_ISERIES */ | ||
107 | |||
127 | . = 0x60 | 108 | . = 0x60 |
128 | /* | 109 | /* |
129 | * The following code is used on pSeries to hold secondary processors | 110 | * The following code is used on pSeries to hold secondary processors |
@@ -1602,9 +1583,6 @@ _GLOBAL(__start_initialization_multiplatform) | |||
1602 | /* Setup some critical 970 SPRs before switching MMU off */ | 1583 | /* Setup some critical 970 SPRs before switching MMU off */ |
1603 | bl .__970_cpu_preinit | 1584 | bl .__970_cpu_preinit |
1604 | 1585 | ||
1605 | /* cpu # */ | ||
1606 | li r24,0 | ||
1607 | |||
1608 | /* Switch off MMU if not already */ | 1586 | /* Switch off MMU if not already */ |
1609 | LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE) | 1587 | LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE) |
1610 | add r4,r4,r30 | 1588 | add r4,r4,r30 |
@@ -1683,6 +1661,9 @@ _STATIC(__after_prom_start) | |||
1683 | /* i.e. where we are running */ | 1661 | /* i.e. where we are running */ |
1684 | /* the source addr */ | 1662 | /* the source addr */ |
1685 | 1663 | ||
1664 | cmpdi r4,0 /* In some cases the loader may */ | ||
1665 | beq .start_here_multiplatform /* have already put us at zero */ | ||
1666 | /* so we can skip the copy. */ | ||
1686 | LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */ | 1667 | LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */ |
1687 | sub r5,r5,r27 | 1668 | sub r5,r5,r27 |
1688 | 1669 | ||
@@ -1962,14 +1943,6 @@ _STATIC(start_here_common) | |||
1962 | li r3,0 | 1943 | li r3,0 |
1963 | bl .do_cpu_ftr_fixups | 1944 | bl .do_cpu_ftr_fixups |
1964 | 1945 | ||
1965 | LOAD_REG_IMMEDIATE(r26, boot_cpuid) | ||
1966 | lwz r26,0(r26) | ||
1967 | |||
1968 | LOAD_REG_IMMEDIATE(r24, paca) /* Get base vaddr of paca array */ | ||
1969 | mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */ | ||
1970 | add r13,r13,r24 /* for this processor. */ | ||
1971 | mtspr SPRN_SPRG3,r13 | ||
1972 | |||
1973 | /* ptr to current */ | 1946 | /* ptr to current */ |
1974 | LOAD_REG_IMMEDIATE(r4, init_task) | 1947 | LOAD_REG_IMMEDIATE(r4, init_task) |
1975 | std r4,PACACURRENT(r13) | 1948 | std r4,PACACURRENT(r13) |
@@ -1995,17 +1968,6 @@ _STATIC(start_here_common) | |||
1995 | /* Not reached */ | 1968 | /* Not reached */ |
1996 | BUG_OPCODE | 1969 | BUG_OPCODE |
1997 | 1970 | ||
1998 | /* Put the paca pointer into r13 and SPRG3 */ | ||
1999 | _GLOBAL(setup_boot_paca) | ||
2000 | LOAD_REG_IMMEDIATE(r3, boot_cpuid) | ||
2001 | lwz r3,0(r3) | ||
2002 | LOAD_REG_IMMEDIATE(r4, paca) /* Get base vaddr of paca array */ | ||
2003 | mulli r3,r3,PACA_SIZE /* Calculate vaddr of right paca */ | ||
2004 | add r13,r3,r4 /* for this processor. */ | ||
2005 | mtspr SPRN_SPRG3,r13 | ||
2006 | |||
2007 | blr | ||
2008 | |||
2009 | /* | 1971 | /* |
2010 | * We put a few things here that have to be page-aligned. | 1972 | * We put a few things here that have to be page-aligned. |
2011 | * This stuff goes at the beginning of the bss, which is page-aligned. | 1973 | * This stuff goes at the beginning of the bss, which is page-aligned. |
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 7cb77c20fc5d..3d677ac99659 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <asm/iommu.h> | 38 | #include <asm/iommu.h> |
39 | #include <asm/pci-bridge.h> | 39 | #include <asm/pci-bridge.h> |
40 | #include <asm/machdep.h> | 40 | #include <asm/machdep.h> |
41 | #include <asm/kdump.h> | ||
41 | 42 | ||
42 | #define DBG(...) | 43 | #define DBG(...) |
43 | 44 | ||
@@ -440,8 +441,37 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) | |||
440 | tbl->it_largehint = tbl->it_halfpoint; | 441 | tbl->it_largehint = tbl->it_halfpoint; |
441 | spin_lock_init(&tbl->it_lock); | 442 | spin_lock_init(&tbl->it_lock); |
442 | 443 | ||
444 | #ifdef CONFIG_CRASH_DUMP | ||
445 | if (ppc_md.tce_get) { | ||
446 | unsigned long index, tceval; | ||
447 | unsigned long tcecount = 0; | ||
448 | |||
449 | /* | ||
450 | * Reserve the existing mappings left by the first kernel. | ||
451 | */ | ||
452 | for (index = 0; index < tbl->it_size; index++) { | ||
453 | tceval = ppc_md.tce_get(tbl, index + tbl->it_offset); | ||
454 | /* | ||
455 | * Freed TCE entry contains 0x7fffffffffffffff on JS20 | ||
456 | */ | ||
457 | if (tceval && (tceval != 0x7fffffffffffffffUL)) { | ||
458 | __set_bit(index, tbl->it_map); | ||
459 | tcecount++; | ||
460 | } | ||
461 | } | ||
462 | if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) { | ||
463 | printk(KERN_WARNING "TCE table is full; "); | ||
464 | printk(KERN_WARNING "freeing %d entries for the kdump boot\n", | ||
465 | KDUMP_MIN_TCE_ENTRIES); | ||
466 | for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES; | ||
467 | index < tbl->it_size; index++) | ||
468 | __clear_bit(index, tbl->it_map); | ||
469 | } | ||
470 | } | ||
471 | #else | ||
443 | /* Clear the hardware table in case firmware left allocations in it */ | 472 | /* Clear the hardware table in case firmware left allocations in it */ |
444 | ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); | 473 | ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); |
474 | #endif | ||
445 | 475 | ||
446 | if (!welcomed) { | 476 | if (!welcomed) { |
447 | printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", | 477 | printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", |
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 6e67b5b49ba1..3a9b78d03542 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c | |||
@@ -302,6 +302,17 @@ void __init find_legacy_serial_ports(void) | |||
302 | of_node_put(isa); | 302 | of_node_put(isa); |
303 | } | 303 | } |
304 | 304 | ||
305 | /* First fill our array with tsi-bridge ports */ | ||
306 | for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) { | ||
307 | struct device_node *tsi = of_get_parent(np); | ||
308 | if (tsi && !strcmp(tsi->type, "tsi-bridge")) { | ||
309 | index = add_legacy_soc_port(np, np); | ||
310 | if (index >= 0 && np == stdout) | ||
311 | legacy_serial_console = index; | ||
312 | } | ||
313 | of_node_put(tsi); | ||
314 | } | ||
315 | |||
305 | #ifdef CONFIG_PCI | 316 | #ifdef CONFIG_PCI |
306 | /* Next, try to locate PCI ports */ | 317 | /* Next, try to locate PCI ports */ |
307 | for (np = NULL; (np = of_find_all_nodes(np));) { | 318 | for (np = NULL; (np = of_find_all_nodes(np));) { |
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index c02deaab26c7..73edc3c16137 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c | |||
@@ -45,11 +45,9 @@ | |||
45 | static struct proc_dir_entry *proc_ppc64_lparcfg; | 45 | static struct proc_dir_entry *proc_ppc64_lparcfg; |
46 | #define LPARCFG_BUFF_SIZE 4096 | 46 | #define LPARCFG_BUFF_SIZE 4096 |
47 | 47 | ||
48 | #ifdef CONFIG_PPC_ISERIES | ||
49 | |||
50 | /* | 48 | /* |
51 | * For iSeries legacy systems, the PPA purr function is available from the | 49 | * Track sum of all purrs across all processors. This is used to further |
52 | * emulated_time_base field in the paca. | 50 | * calculate usage values by different applications |
53 | */ | 51 | */ |
54 | static unsigned long get_purr(void) | 52 | static unsigned long get_purr(void) |
55 | { | 53 | { |
@@ -57,48 +55,31 @@ static unsigned long get_purr(void) | |||
57 | int cpu; | 55 | int cpu; |
58 | 56 | ||
59 | for_each_possible_cpu(cpu) { | 57 | for_each_possible_cpu(cpu) { |
60 | sum_purr += lppaca[cpu].emulated_time_base; | 58 | if (firmware_has_feature(FW_FEATURE_ISERIES)) |
59 | sum_purr += lppaca[cpu].emulated_time_base; | ||
60 | else { | ||
61 | struct cpu_usage *cu; | ||
61 | 62 | ||
62 | #ifdef PURR_DEBUG | 63 | cu = &per_cpu(cpu_usage_array, cpu); |
63 | printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n", | 64 | sum_purr += cu->current_tb; |
64 | cpu, lppaca[cpu].emulated_time_base); | 65 | } |
65 | #endif | ||
66 | } | 66 | } |
67 | return sum_purr; | 67 | return sum_purr; |
68 | } | 68 | } |
69 | 69 | ||
70 | #define lparcfg_write NULL | 70 | #ifdef CONFIG_PPC_ISERIES |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * Methods used to fetch LPAR data when running on an iSeries platform. | 73 | * Methods used to fetch LPAR data when running on an iSeries platform. |
74 | */ | 74 | */ |
75 | static int lparcfg_data(struct seq_file *m, void *v) | 75 | static int iseries_lparcfg_data(struct seq_file *m, void *v) |
76 | { | 76 | { |
77 | unsigned long pool_id, lp_index; | 77 | unsigned long pool_id; |
78 | int shared, entitled_capacity, max_entitled_capacity; | 78 | int shared, entitled_capacity, max_entitled_capacity; |
79 | int processors, max_processors; | 79 | int processors, max_processors; |
80 | unsigned long purr = get_purr(); | 80 | unsigned long purr = get_purr(); |
81 | 81 | ||
82 | seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); | ||
83 | |||
84 | shared = (int)(get_lppaca()->shared_proc); | 82 | shared = (int)(get_lppaca()->shared_proc); |
85 | seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n", | ||
86 | e2a(xItExtVpdPanel.mfgID[2]), | ||
87 | e2a(xItExtVpdPanel.mfgID[3]), | ||
88 | e2a(xItExtVpdPanel.systemSerial[1]), | ||
89 | e2a(xItExtVpdPanel.systemSerial[2]), | ||
90 | e2a(xItExtVpdPanel.systemSerial[3]), | ||
91 | e2a(xItExtVpdPanel.systemSerial[4]), | ||
92 | e2a(xItExtVpdPanel.systemSerial[5])); | ||
93 | |||
94 | seq_printf(m, "system_type=%c%c%c%c\n", | ||
95 | e2a(xItExtVpdPanel.machineType[0]), | ||
96 | e2a(xItExtVpdPanel.machineType[1]), | ||
97 | e2a(xItExtVpdPanel.machineType[2]), | ||
98 | e2a(xItExtVpdPanel.machineType[3])); | ||
99 | |||
100 | lp_index = HvLpConfig_getLpIndex(); | ||
101 | seq_printf(m, "partition_id=%d\n", (int)lp_index); | ||
102 | 83 | ||
103 | seq_printf(m, "system_active_processors=%d\n", | 84 | seq_printf(m, "system_active_processors=%d\n", |
104 | (int)HvLpConfig_getSystemPhysicalProcessors()); | 85 | (int)HvLpConfig_getSystemPhysicalProcessors()); |
@@ -137,6 +118,14 @@ static int lparcfg_data(struct seq_file *m, void *v) | |||
137 | 118 | ||
138 | return 0; | 119 | return 0; |
139 | } | 120 | } |
121 | |||
122 | #else /* CONFIG_PPC_ISERIES */ | ||
123 | |||
124 | static int iseries_lparcfg_data(struct seq_file *m, void *v) | ||
125 | { | ||
126 | return 0; | ||
127 | } | ||
128 | |||
140 | #endif /* CONFIG_PPC_ISERIES */ | 129 | #endif /* CONFIG_PPC_ISERIES */ |
141 | 130 | ||
142 | #ifdef CONFIG_PPC_PSERIES | 131 | #ifdef CONFIG_PPC_PSERIES |
@@ -213,22 +202,6 @@ static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs) | |||
213 | log_plpar_hcall_return(rc, "H_PIC"); | 202 | log_plpar_hcall_return(rc, "H_PIC"); |
214 | } | 203 | } |
215 | 204 | ||
216 | /* Track sum of all purrs across all processors. This is used to further */ | ||
217 | /* calculate usage values by different applications */ | ||
218 | |||
219 | static unsigned long get_purr(void) | ||
220 | { | ||
221 | unsigned long sum_purr = 0; | ||
222 | int cpu; | ||
223 | struct cpu_usage *cu; | ||
224 | |||
225 | for_each_possible_cpu(cpu) { | ||
226 | cu = &per_cpu(cpu_usage_array, cpu); | ||
227 | sum_purr += cu->current_tb; | ||
228 | } | ||
229 | return sum_purr; | ||
230 | } | ||
231 | |||
232 | #define SPLPAR_CHARACTERISTICS_TOKEN 20 | 205 | #define SPLPAR_CHARACTERISTICS_TOKEN 20 |
233 | #define SPLPAR_MAXLENGTH 1026*(sizeof(char)) | 206 | #define SPLPAR_MAXLENGTH 1026*(sizeof(char)) |
234 | 207 | ||
@@ -333,35 +306,13 @@ static int lparcfg_count_active_processors(void) | |||
333 | return count; | 306 | return count; |
334 | } | 307 | } |
335 | 308 | ||
336 | static int lparcfg_data(struct seq_file *m, void *v) | 309 | static int pseries_lparcfg_data(struct seq_file *m, void *v) |
337 | { | 310 | { |
338 | int partition_potential_processors; | 311 | int partition_potential_processors; |
339 | int partition_active_processors; | 312 | int partition_active_processors; |
340 | struct device_node *rootdn; | ||
341 | const char *model = ""; | ||
342 | const char *system_id = ""; | ||
343 | unsigned int *lp_index_ptr, lp_index = 0; | ||
344 | struct device_node *rtas_node; | 313 | struct device_node *rtas_node; |
345 | int *lrdrp = NULL; | 314 | int *lrdrp = NULL; |
346 | 315 | ||
347 | rootdn = find_path_device("/"); | ||
348 | if (rootdn) { | ||
349 | model = get_property(rootdn, "model", NULL); | ||
350 | system_id = get_property(rootdn, "system-id", NULL); | ||
351 | lp_index_ptr = (unsigned int *) | ||
352 | get_property(rootdn, "ibm,partition-no", NULL); | ||
353 | if (lp_index_ptr) | ||
354 | lp_index = *lp_index_ptr; | ||
355 | } | ||
356 | |||
357 | seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); | ||
358 | |||
359 | seq_printf(m, "serial_number=%s\n", system_id); | ||
360 | |||
361 | seq_printf(m, "system_type=%s\n", model); | ||
362 | |||
363 | seq_printf(m, "partition_id=%d\n", (int)lp_index); | ||
364 | |||
365 | rtas_node = find_path_device("/rtas"); | 316 | rtas_node = find_path_device("/rtas"); |
366 | if (rtas_node) | 317 | if (rtas_node) |
367 | lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", | 318 | lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", |
@@ -549,8 +500,61 @@ out: | |||
549 | return retval; | 500 | return retval; |
550 | } | 501 | } |
551 | 502 | ||
503 | #else /* CONFIG_PPC_PSERIES */ | ||
504 | |||
505 | static int pseries_lparcfg_data(struct seq_file *m, void *v) | ||
506 | { | ||
507 | return 0; | ||
508 | } | ||
509 | |||
510 | static ssize_t lparcfg_write(struct file *file, const char __user * buf, | ||
511 | size_t count, loff_t * off) | ||
512 | { | ||
513 | return count; | ||
514 | } | ||
515 | |||
552 | #endif /* CONFIG_PPC_PSERIES */ | 516 | #endif /* CONFIG_PPC_PSERIES */ |
553 | 517 | ||
518 | static int lparcfg_data(struct seq_file *m, void *v) | ||
519 | { | ||
520 | struct device_node *rootdn; | ||
521 | const char *model = ""; | ||
522 | const char *system_id = ""; | ||
523 | const char *tmp; | ||
524 | unsigned int *lp_index_ptr, lp_index = 0; | ||
525 | |||
526 | seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); | ||
527 | |||
528 | rootdn = find_path_device("/"); | ||
529 | if (rootdn) { | ||
530 | tmp = get_property(rootdn, "model", NULL); | ||
531 | if (tmp) { | ||
532 | model = tmp; | ||
533 | /* Skip "IBM," - see platforms/iseries/dt.c */ | ||
534 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
535 | model += 4; | ||
536 | } | ||
537 | tmp = get_property(rootdn, "system-id", NULL); | ||
538 | if (tmp) { | ||
539 | system_id = tmp; | ||
540 | /* Skip "IBM," - see platforms/iseries/dt.c */ | ||
541 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
542 | system_id += 4; | ||
543 | } | ||
544 | lp_index_ptr = (unsigned int *) | ||
545 | get_property(rootdn, "ibm,partition-no", NULL); | ||
546 | if (lp_index_ptr) | ||
547 | lp_index = *lp_index_ptr; | ||
548 | } | ||
549 | seq_printf(m, "serial_number=%s\n", system_id); | ||
550 | seq_printf(m, "system_type=%s\n", model); | ||
551 | seq_printf(m, "partition_id=%d\n", (int)lp_index); | ||
552 | |||
553 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
554 | return iseries_lparcfg_data(m, v); | ||
555 | return pseries_lparcfg_data(m, v); | ||
556 | } | ||
557 | |||
554 | static int lparcfg_open(struct inode *inode, struct file *file) | 558 | static int lparcfg_open(struct inode *inode, struct file *file) |
555 | { | 559 | { |
556 | return single_open(file, lparcfg_data, NULL); | 560 | return single_open(file, lparcfg_data, NULL); |
@@ -569,7 +573,8 @@ int __init lparcfg_init(void) | |||
569 | mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; | 573 | mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; |
570 | 574 | ||
571 | /* Allow writing if we have FW_FEATURE_SPLPAR */ | 575 | /* Allow writing if we have FW_FEATURE_SPLPAR */ |
572 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) { | 576 | if (firmware_has_feature(FW_FEATURE_SPLPAR) && |
577 | !firmware_has_feature(FW_FEATURE_ISERIES)) { | ||
573 | lparcfg_fops.write = lparcfg_write; | 578 | lparcfg_fops.write = lparcfg_write; |
574 | mode |= S_IWUSR; | 579 | mode |= S_IWUSR; |
575 | } | 580 | } |
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index a8fa04ef27cd..b438d45a068c 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
@@ -378,11 +378,13 @@ static void __init export_crashk_values(void) | |||
378 | of_node_put(node); | 378 | of_node_put(node); |
379 | } | 379 | } |
380 | 380 | ||
381 | void __init kexec_setup(void) | 381 | static int __init kexec_setup(void) |
382 | { | 382 | { |
383 | export_htab_values(); | 383 | export_htab_values(); |
384 | export_crashk_values(); | 384 | export_crashk_values(); |
385 | return 0; | ||
385 | } | 386 | } |
387 | __initcall(kexec_setup); | ||
386 | 388 | ||
387 | static int __init early_parse_crashk(char *p) | 389 | static int __init early_parse_crashk(char *p) |
388 | { | 390 | { |
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S new file mode 100644 index 000000000000..fc23040d5a26 --- /dev/null +++ b/arch/powerpc/kernel/misc.S | |||
@@ -0,0 +1,203 @@ | |||
1 | /* | ||
2 | * This file contains miscellaneous low-level functions. | ||
3 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | ||
4 | * | ||
5 | * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) | ||
6 | * and Paul Mackerras. | ||
7 | * | ||
8 | * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) | ||
9 | * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version | ||
14 | * 2 of the License, or (at your option) any later version. | ||
15 | */ | ||
16 | #include <asm/ppc_asm.h> | ||
17 | |||
18 | .text | ||
19 | |||
20 | #ifdef CONFIG_PPC64 | ||
21 | #define IN_SYNC twi 0,r5,0; isync | ||
22 | #define EIEIO_32 | ||
23 | #define SYNC_64 sync | ||
24 | #else /* CONFIG_PPC32 */ | ||
25 | #define IN_SYNC | ||
26 | #define EIEIO_32 eieio | ||
27 | #define SYNC_64 | ||
28 | #endif | ||
29 | /* | ||
30 | * Returns (address we are running at) - (address we were linked at) | ||
31 | * for use before the text and data are mapped to KERNELBASE. | ||
32 | */ | ||
33 | |||
34 | _GLOBAL(reloc_offset) | ||
35 | mflr r0 | ||
36 | bl 1f | ||
37 | 1: mflr r3 | ||
38 | LOAD_REG_IMMEDIATE(r4,1b) | ||
39 | subf r3,r4,r3 | ||
40 | mtlr r0 | ||
41 | blr | ||
42 | |||
43 | /* | ||
44 | * add_reloc_offset(x) returns x + reloc_offset(). | ||
45 | */ | ||
46 | _GLOBAL(add_reloc_offset) | ||
47 | mflr r0 | ||
48 | bl 1f | ||
49 | 1: mflr r5 | ||
50 | LOAD_REG_IMMEDIATE(r4,1b) | ||
51 | subf r5,r4,r5 | ||
52 | add r3,r3,r5 | ||
53 | mtlr r0 | ||
54 | blr | ||
55 | |||
56 | /* | ||
57 | * I/O string operations | ||
58 | * | ||
59 | * insb(port, buf, len) | ||
60 | * outsb(port, buf, len) | ||
61 | * insw(port, buf, len) | ||
62 | * outsw(port, buf, len) | ||
63 | * insl(port, buf, len) | ||
64 | * outsl(port, buf, len) | ||
65 | * insw_ns(port, buf, len) | ||
66 | * outsw_ns(port, buf, len) | ||
67 | * insl_ns(port, buf, len) | ||
68 | * outsl_ns(port, buf, len) | ||
69 | * | ||
70 | * The *_ns versions don't do byte-swapping. | ||
71 | */ | ||
72 | _GLOBAL(_insb) | ||
73 | cmpwi 0,r5,0 | ||
74 | mtctr r5 | ||
75 | subi r4,r4,1 | ||
76 | blelr- | ||
77 | 00: lbz r5,0(r3) | ||
78 | eieio | ||
79 | stbu r5,1(r4) | ||
80 | bdnz 00b | ||
81 | IN_SYNC | ||
82 | blr | ||
83 | |||
84 | _GLOBAL(_outsb) | ||
85 | cmpwi 0,r5,0 | ||
86 | mtctr r5 | ||
87 | subi r4,r4,1 | ||
88 | blelr- | ||
89 | 00: lbzu r5,1(r4) | ||
90 | stb r5,0(r3) | ||
91 | EIEIO_32 | ||
92 | bdnz 00b | ||
93 | SYNC_64 | ||
94 | blr | ||
95 | |||
96 | _GLOBAL(_insw) | ||
97 | cmpwi 0,r5,0 | ||
98 | mtctr r5 | ||
99 | subi r4,r4,2 | ||
100 | blelr- | ||
101 | 00: lhbrx r5,0,r3 | ||
102 | eieio | ||
103 | sthu r5,2(r4) | ||
104 | bdnz 00b | ||
105 | IN_SYNC | ||
106 | blr | ||
107 | |||
108 | _GLOBAL(_outsw) | ||
109 | cmpwi 0,r5,0 | ||
110 | mtctr r5 | ||
111 | subi r4,r4,2 | ||
112 | blelr- | ||
113 | 00: lhzu r5,2(r4) | ||
114 | EIEIO_32 | ||
115 | sthbrx r5,0,r3 | ||
116 | bdnz 00b | ||
117 | SYNC_64 | ||
118 | blr | ||
119 | |||
120 | _GLOBAL(_insl) | ||
121 | cmpwi 0,r5,0 | ||
122 | mtctr r5 | ||
123 | subi r4,r4,4 | ||
124 | blelr- | ||
125 | 00: lwbrx r5,0,r3 | ||
126 | eieio | ||
127 | stwu r5,4(r4) | ||
128 | bdnz 00b | ||
129 | IN_SYNC | ||
130 | blr | ||
131 | |||
132 | _GLOBAL(_outsl) | ||
133 | cmpwi 0,r5,0 | ||
134 | mtctr r5 | ||
135 | subi r4,r4,4 | ||
136 | blelr- | ||
137 | 00: lwzu r5,4(r4) | ||
138 | stwbrx r5,0,r3 | ||
139 | EIEIO_32 | ||
140 | bdnz 00b | ||
141 | SYNC_64 | ||
142 | blr | ||
143 | |||
144 | #ifdef CONFIG_PPC32 | ||
145 | _GLOBAL(__ide_mm_insw) | ||
146 | #endif | ||
147 | _GLOBAL(_insw_ns) | ||
148 | cmpwi 0,r5,0 | ||
149 | mtctr r5 | ||
150 | subi r4,r4,2 | ||
151 | blelr- | ||
152 | 00: lhz r5,0(r3) | ||
153 | eieio | ||
154 | sthu r5,2(r4) | ||
155 | bdnz 00b | ||
156 | IN_SYNC | ||
157 | blr | ||
158 | |||
159 | #ifdef CONFIG_PPC32 | ||
160 | _GLOBAL(__ide_mm_outsw) | ||
161 | #endif | ||
162 | _GLOBAL(_outsw_ns) | ||
163 | cmpwi 0,r5,0 | ||
164 | mtctr r5 | ||
165 | subi r4,r4,2 | ||
166 | blelr- | ||
167 | 00: lhzu r5,2(r4) | ||
168 | sth r5,0(r3) | ||
169 | EIEIO_32 | ||
170 | bdnz 00b | ||
171 | SYNC_64 | ||
172 | blr | ||
173 | |||
174 | #ifdef CONFIG_PPC32 | ||
175 | _GLOBAL(__ide_mm_insl) | ||
176 | #endif | ||
177 | _GLOBAL(_insl_ns) | ||
178 | cmpwi 0,r5,0 | ||
179 | mtctr r5 | ||
180 | subi r4,r4,4 | ||
181 | blelr- | ||
182 | 00: lwz r5,0(r3) | ||
183 | eieio | ||
184 | stwu r5,4(r4) | ||
185 | bdnz 00b | ||
186 | IN_SYNC | ||
187 | blr | ||
188 | |||
189 | #ifdef CONFIG_PPC32 | ||
190 | _GLOBAL(__ide_mm_outsl) | ||
191 | #endif | ||
192 | _GLOBAL(_outsl_ns) | ||
193 | cmpwi 0,r5,0 | ||
194 | mtctr r5 | ||
195 | subi r4,r4,4 | ||
196 | blelr- | ||
197 | 00: lwzu r5,4(r4) | ||
198 | stw r5,0(r3) | ||
199 | EIEIO_32 | ||
200 | bdnz 00b | ||
201 | SYNC_64 | ||
202 | blr | ||
203 | |||
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 01d3916c4cb1..c74774e2175d 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -61,32 +61,6 @@ _GLOBAL(mulhdu) | |||
61 | blr | 61 | blr |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * Returns (address we're running at) - (address we were linked at) | ||
65 | * for use before the text and data are mapped to KERNELBASE. | ||
66 | */ | ||
67 | _GLOBAL(reloc_offset) | ||
68 | mflr r0 | ||
69 | bl 1f | ||
70 | 1: mflr r3 | ||
71 | LOAD_REG_IMMEDIATE(r4,1b) | ||
72 | subf r3,r4,r3 | ||
73 | mtlr r0 | ||
74 | blr | ||
75 | |||
76 | /* | ||
77 | * add_reloc_offset(x) returns x + reloc_offset(). | ||
78 | */ | ||
79 | _GLOBAL(add_reloc_offset) | ||
80 | mflr r0 | ||
81 | bl 1f | ||
82 | 1: mflr r5 | ||
83 | LOAD_REG_IMMEDIATE(r4,1b) | ||
84 | subf r5,r4,r5 | ||
85 | add r3,r3,r5 | ||
86 | mtlr r0 | ||
87 | blr | ||
88 | |||
89 | /* | ||
90 | * sub_reloc_offset(x) returns x - reloc_offset(). | 64 | * sub_reloc_offset(x) returns x - reloc_offset(). |
91 | */ | 65 | */ |
92 | _GLOBAL(sub_reloc_offset) | 66 | _GLOBAL(sub_reloc_offset) |
@@ -781,136 +755,6 @@ _GLOBAL(atomic_set_mask) | |||
781 | blr | 755 | blr |
782 | 756 | ||
783 | /* | 757 | /* |
784 | * I/O string operations | ||
785 | * | ||
786 | * insb(port, buf, len) | ||
787 | * outsb(port, buf, len) | ||
788 | * insw(port, buf, len) | ||
789 | * outsw(port, buf, len) | ||
790 | * insl(port, buf, len) | ||
791 | * outsl(port, buf, len) | ||
792 | * insw_ns(port, buf, len) | ||
793 | * outsw_ns(port, buf, len) | ||
794 | * insl_ns(port, buf, len) | ||
795 | * outsl_ns(port, buf, len) | ||
796 | * | ||
797 | * The *_ns versions don't do byte-swapping. | ||
798 | */ | ||
799 | _GLOBAL(_insb) | ||
800 | cmpwi 0,r5,0 | ||
801 | mtctr r5 | ||
802 | subi r4,r4,1 | ||
803 | blelr- | ||
804 | 00: lbz r5,0(r3) | ||
805 | eieio | ||
806 | stbu r5,1(r4) | ||
807 | bdnz 00b | ||
808 | blr | ||
809 | |||
810 | _GLOBAL(_outsb) | ||
811 | cmpwi 0,r5,0 | ||
812 | mtctr r5 | ||
813 | subi r4,r4,1 | ||
814 | blelr- | ||
815 | 00: lbzu r5,1(r4) | ||
816 | stb r5,0(r3) | ||
817 | eieio | ||
818 | bdnz 00b | ||
819 | blr | ||
820 | |||
821 | _GLOBAL(_insw) | ||
822 | cmpwi 0,r5,0 | ||
823 | mtctr r5 | ||
824 | subi r4,r4,2 | ||
825 | blelr- | ||
826 | 00: lhbrx r5,0,r3 | ||
827 | eieio | ||
828 | sthu r5,2(r4) | ||
829 | bdnz 00b | ||
830 | blr | ||
831 | |||
832 | _GLOBAL(_outsw) | ||
833 | cmpwi 0,r5,0 | ||
834 | mtctr r5 | ||
835 | subi r4,r4,2 | ||
836 | blelr- | ||
837 | 00: lhzu r5,2(r4) | ||
838 | eieio | ||
839 | sthbrx r5,0,r3 | ||
840 | bdnz 00b | ||
841 | blr | ||
842 | |||
843 | _GLOBAL(_insl) | ||
844 | cmpwi 0,r5,0 | ||
845 | mtctr r5 | ||
846 | subi r4,r4,4 | ||
847 | blelr- | ||
848 | 00: lwbrx r5,0,r3 | ||
849 | eieio | ||
850 | stwu r5,4(r4) | ||
851 | bdnz 00b | ||
852 | blr | ||
853 | |||
854 | _GLOBAL(_outsl) | ||
855 | cmpwi 0,r5,0 | ||
856 | mtctr r5 | ||
857 | subi r4,r4,4 | ||
858 | blelr- | ||
859 | 00: lwzu r5,4(r4) | ||
860 | stwbrx r5,0,r3 | ||
861 | eieio | ||
862 | bdnz 00b | ||
863 | blr | ||
864 | |||
865 | _GLOBAL(__ide_mm_insw) | ||
866 | _GLOBAL(_insw_ns) | ||
867 | cmpwi 0,r5,0 | ||
868 | mtctr r5 | ||
869 | subi r4,r4,2 | ||
870 | blelr- | ||
871 | 00: lhz r5,0(r3) | ||
872 | eieio | ||
873 | sthu r5,2(r4) | ||
874 | bdnz 00b | ||
875 | blr | ||
876 | |||
877 | _GLOBAL(__ide_mm_outsw) | ||
878 | _GLOBAL(_outsw_ns) | ||
879 | cmpwi 0,r5,0 | ||
880 | mtctr r5 | ||
881 | subi r4,r4,2 | ||
882 | blelr- | ||
883 | 00: lhzu r5,2(r4) | ||
884 | sth r5,0(r3) | ||
885 | eieio | ||
886 | bdnz 00b | ||
887 | blr | ||
888 | |||
889 | _GLOBAL(__ide_mm_insl) | ||
890 | _GLOBAL(_insl_ns) | ||
891 | cmpwi 0,r5,0 | ||
892 | mtctr r5 | ||
893 | subi r4,r4,4 | ||
894 | blelr- | ||
895 | 00: lwz r5,0(r3) | ||
896 | eieio | ||
897 | stwu r5,4(r4) | ||
898 | bdnz 00b | ||
899 | blr | ||
900 | |||
901 | _GLOBAL(__ide_mm_outsl) | ||
902 | _GLOBAL(_outsl_ns) | ||
903 | cmpwi 0,r5,0 | ||
904 | mtctr r5 | ||
905 | subi r4,r4,4 | ||
906 | blelr- | ||
907 | 00: lwzu r5,4(r4) | ||
908 | stw r5,0(r3) | ||
909 | eieio | ||
910 | bdnz 00b | ||
911 | blr | ||
912 | |||
913 | /* | ||
914 | * Extended precision shifts. | 758 | * Extended precision shifts. |
915 | * | 759 | * |
916 | * Updated to be valid for shift counts from 0 to 63 inclusive. | 760 | * Updated to be valid for shift counts from 0 to 63 inclusive. |
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index e8883d42c43c..580891cb8ccb 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * arch/powerpc/kernel/misc64.S | ||
3 | * | ||
4 | * This file contains miscellaneous low-level functions. | 2 | * This file contains miscellaneous low-level functions. |
5 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | 3 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) |
6 | * | 4 | * |
7 | * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) | 5 | * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) |
8 | * and Paul Mackerras. | 6 | * and Paul Mackerras. |
9 | * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) | 7 | * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) |
10 | * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) | 8 | * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) |
11 | * | 9 | * |
12 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License | 11 | * modify it under the terms of the GNU General Public License |
14 | * as published by the Free Software Foundation; either version | 12 | * as published by the Free Software Foundation; either version |
@@ -30,41 +28,10 @@ | |||
30 | 28 | ||
31 | .text | 29 | .text |
32 | 30 | ||
33 | /* | ||
34 | * Returns (address we are running at) - (address we were linked at) | ||
35 | * for use before the text and data are mapped to KERNELBASE. | ||
36 | */ | ||
37 | |||
38 | _GLOBAL(reloc_offset) | ||
39 | mflr r0 | ||
40 | bl 1f | ||
41 | 1: mflr r3 | ||
42 | LOAD_REG_IMMEDIATE(r4,1b) | ||
43 | subf r3,r4,r3 | ||
44 | mtlr r0 | ||
45 | blr | ||
46 | |||
47 | /* | ||
48 | * add_reloc_offset(x) returns x + reloc_offset(). | ||
49 | */ | ||
50 | _GLOBAL(add_reloc_offset) | ||
51 | mflr r0 | ||
52 | bl 1f | ||
53 | 1: mflr r5 | ||
54 | LOAD_REG_IMMEDIATE(r4,1b) | ||
55 | subf r5,r4,r5 | ||
56 | add r3,r3,r5 | ||
57 | mtlr r0 | ||
58 | blr | ||
59 | |||
60 | _GLOBAL(get_msr) | 31 | _GLOBAL(get_msr) |
61 | mfmsr r3 | 32 | mfmsr r3 |
62 | blr | 33 | blr |
63 | 34 | ||
64 | _GLOBAL(get_dar) | ||
65 | mfdar r3 | ||
66 | blr | ||
67 | |||
68 | _GLOBAL(get_srr0) | 35 | _GLOBAL(get_srr0) |
69 | mfsrr0 r3 | 36 | mfsrr0 r3 |
70 | blr | 37 | blr |
@@ -72,10 +39,6 @@ _GLOBAL(get_srr0) | |||
72 | _GLOBAL(get_srr1) | 39 | _GLOBAL(get_srr1) |
73 | mfsrr1 r3 | 40 | mfsrr1 r3 |
74 | blr | 41 | blr |
75 | |||
76 | _GLOBAL(get_sp) | ||
77 | mr r3,r1 | ||
78 | blr | ||
79 | 42 | ||
80 | #ifdef CONFIG_IRQSTACKS | 43 | #ifdef CONFIG_IRQSTACKS |
81 | _GLOBAL(call_do_softirq) | 44 | _GLOBAL(call_do_softirq) |
@@ -101,48 +64,6 @@ _GLOBAL(call___do_IRQ) | |||
101 | blr | 64 | blr |
102 | #endif /* CONFIG_IRQSTACKS */ | 65 | #endif /* CONFIG_IRQSTACKS */ |
103 | 66 | ||
104 | /* | ||
105 | * To be called by C code which needs to do some operations with MMU | ||
106 | * disabled. Note that interrupts have to be disabled by the caller | ||
107 | * prior to calling us. The code called _MUST_ be in the RMO of course | ||
108 | * and part of the linear mapping as we don't attempt to translate the | ||
109 | * stack pointer at all. The function is called with the stack switched | ||
110 | * to this CPU emergency stack | ||
111 | * | ||
112 | * prototype is void *call_with_mmu_off(void *func, void *data); | ||
113 | * | ||
114 | * the called function is expected to be of the form | ||
115 | * | ||
116 | * void *called(void *data); | ||
117 | */ | ||
118 | _GLOBAL(call_with_mmu_off) | ||
119 | mflr r0 /* get link, save it on stackframe */ | ||
120 | std r0,16(r1) | ||
121 | mr r1,r5 /* save old stack ptr */ | ||
122 | ld r1,PACAEMERGSP(r13) /* get emerg. stack */ | ||
123 | subi r1,r1,STACK_FRAME_OVERHEAD | ||
124 | std r0,16(r1) /* save link on emerg. stack */ | ||
125 | std r5,0(r1) /* save old stack ptr in backchain */ | ||
126 | ld r3,0(r3) /* get to real function ptr (assume same TOC) */ | ||
127 | bl 2f /* we need LR to return, continue at label 2 */ | ||
128 | |||
129 | ld r0,16(r1) /* we return here from the call, get LR and */ | ||
130 | ld r1,0(r1) /* .. old stack ptr */ | ||
131 | mtspr SPRN_SRR0,r0 /* and get back to virtual mode with these */ | ||
132 | mfmsr r4 | ||
133 | ori r4,r4,MSR_IR|MSR_DR | ||
134 | mtspr SPRN_SRR1,r4 | ||
135 | rfid | ||
136 | |||
137 | 2: mtspr SPRN_SRR0,r3 /* coming from above, enter real mode */ | ||
138 | mr r3,r4 /* get parameter */ | ||
139 | mfmsr r0 | ||
140 | ori r0,r0,MSR_IR|MSR_DR | ||
141 | xori r0,r0,MSR_IR|MSR_DR | ||
142 | mtspr SPRN_SRR1,r0 | ||
143 | rfid | ||
144 | |||
145 | |||
146 | .section ".toc","aw" | 67 | .section ".toc","aw" |
147 | PPC64_CACHES: | 68 | PPC64_CACHES: |
148 | .tc ppc64_caches[TC],ppc64_caches | 69 | .tc ppc64_caches[TC],ppc64_caches |
@@ -323,144 +244,6 @@ _GLOBAL(__flush_dcache_icache) | |||
323 | bdnz 1b | 244 | bdnz 1b |
324 | isync | 245 | isync |
325 | blr | 246 | blr |
326 | |||
327 | /* | ||
328 | * I/O string operations | ||
329 | * | ||
330 | * insb(port, buf, len) | ||
331 | * outsb(port, buf, len) | ||
332 | * insw(port, buf, len) | ||
333 | * outsw(port, buf, len) | ||
334 | * insl(port, buf, len) | ||
335 | * outsl(port, buf, len) | ||
336 | * insw_ns(port, buf, len) | ||
337 | * outsw_ns(port, buf, len) | ||
338 | * insl_ns(port, buf, len) | ||
339 | * outsl_ns(port, buf, len) | ||
340 | * | ||
341 | * The *_ns versions don't do byte-swapping. | ||
342 | */ | ||
343 | _GLOBAL(_insb) | ||
344 | cmpwi 0,r5,0 | ||
345 | mtctr r5 | ||
346 | subi r4,r4,1 | ||
347 | blelr- | ||
348 | 00: lbz r5,0(r3) | ||
349 | eieio | ||
350 | stbu r5,1(r4) | ||
351 | bdnz 00b | ||
352 | twi 0,r5,0 | ||
353 | isync | ||
354 | blr | ||
355 | |||
356 | _GLOBAL(_outsb) | ||
357 | cmpwi 0,r5,0 | ||
358 | mtctr r5 | ||
359 | subi r4,r4,1 | ||
360 | blelr- | ||
361 | 00: lbzu r5,1(r4) | ||
362 | stb r5,0(r3) | ||
363 | bdnz 00b | ||
364 | sync | ||
365 | blr | ||
366 | |||
367 | _GLOBAL(_insw) | ||
368 | cmpwi 0,r5,0 | ||
369 | mtctr r5 | ||
370 | subi r4,r4,2 | ||
371 | blelr- | ||
372 | 00: lhbrx r5,0,r3 | ||
373 | eieio | ||
374 | sthu r5,2(r4) | ||
375 | bdnz 00b | ||
376 | twi 0,r5,0 | ||
377 | isync | ||
378 | blr | ||
379 | |||
380 | _GLOBAL(_outsw) | ||
381 | cmpwi 0,r5,0 | ||
382 | mtctr r5 | ||
383 | subi r4,r4,2 | ||
384 | blelr- | ||
385 | 00: lhzu r5,2(r4) | ||
386 | sthbrx r5,0,r3 | ||
387 | bdnz 00b | ||
388 | sync | ||
389 | blr | ||
390 | |||
391 | _GLOBAL(_insl) | ||
392 | cmpwi 0,r5,0 | ||
393 | mtctr r5 | ||
394 | subi r4,r4,4 | ||
395 | blelr- | ||
396 | 00: lwbrx r5,0,r3 | ||
397 | eieio | ||
398 | stwu r5,4(r4) | ||
399 | bdnz 00b | ||
400 | twi 0,r5,0 | ||
401 | isync | ||
402 | blr | ||
403 | |||
404 | _GLOBAL(_outsl) | ||
405 | cmpwi 0,r5,0 | ||
406 | mtctr r5 | ||
407 | subi r4,r4,4 | ||
408 | blelr- | ||
409 | 00: lwzu r5,4(r4) | ||
410 | stwbrx r5,0,r3 | ||
411 | bdnz 00b | ||
412 | sync | ||
413 | blr | ||
414 | |||
415 | /* _GLOBAL(ide_insw) now in drivers/ide/ide-iops.c */ | ||
416 | _GLOBAL(_insw_ns) | ||
417 | cmpwi 0,r5,0 | ||
418 | mtctr r5 | ||
419 | subi r4,r4,2 | ||
420 | blelr- | ||
421 | 00: lhz r5,0(r3) | ||
422 | eieio | ||
423 | sthu r5,2(r4) | ||
424 | bdnz 00b | ||
425 | twi 0,r5,0 | ||
426 | isync | ||
427 | blr | ||
428 | |||
429 | /* _GLOBAL(ide_outsw) now in drivers/ide/ide-iops.c */ | ||
430 | _GLOBAL(_outsw_ns) | ||
431 | cmpwi 0,r5,0 | ||
432 | mtctr r5 | ||
433 | subi r4,r4,2 | ||
434 | blelr- | ||
435 | 00: lhzu r5,2(r4) | ||
436 | sth r5,0(r3) | ||
437 | bdnz 00b | ||
438 | sync | ||
439 | blr | ||
440 | |||
441 | _GLOBAL(_insl_ns) | ||
442 | cmpwi 0,r5,0 | ||
443 | mtctr r5 | ||
444 | subi r4,r4,4 | ||
445 | blelr- | ||
446 | 00: lwz r5,0(r3) | ||
447 | eieio | ||
448 | stwu r5,4(r4) | ||
449 | bdnz 00b | ||
450 | twi 0,r5,0 | ||
451 | isync | ||
452 | blr | ||
453 | |||
454 | _GLOBAL(_outsl_ns) | ||
455 | cmpwi 0,r5,0 | ||
456 | mtctr r5 | ||
457 | subi r4,r4,4 | ||
458 | blelr- | ||
459 | 00: lwzu r5,4(r4) | ||
460 | stw r5,0(r3) | ||
461 | bdnz 00b | ||
462 | sync | ||
463 | blr | ||
464 | 247 | ||
465 | /* | 248 | /* |
466 | * identify_cpu and calls setup_cpu | 249 | * identify_cpu and calls setup_cpu |
@@ -605,6 +388,7 @@ _GLOBAL(real_writeb) | |||
605 | blr | 388 | blr |
606 | #endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */ | 389 | #endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */ |
607 | 390 | ||
391 | #ifdef CONFIG_CPU_FREQ_PMAC64 | ||
608 | /* | 392 | /* |
609 | * SCOM access functions for 970 (FX only for now) | 393 | * SCOM access functions for 970 (FX only for now) |
610 | * | 394 | * |
@@ -673,6 +457,7 @@ _GLOBAL(scom970_write) | |||
673 | /* restore interrupts */ | 457 | /* restore interrupts */ |
674 | mtmsrd r5,1 | 458 | mtmsrd r5,1 |
675 | blr | 459 | blr |
460 | #endif /* CONFIG_CPU_FREQ_PMAC64 */ | ||
676 | 461 | ||
677 | 462 | ||
678 | /* | 463 | /* |
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index f505a8827e3e..a0bb354c1c08 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <asm/ptrace.h> | 16 | #include <asm/ptrace.h> |
17 | #include <asm/page.h> | 17 | #include <asm/page.h> |
18 | #include <asm/lppaca.h> | 18 | #include <asm/lppaca.h> |
19 | #include <asm/iseries/it_lp_queue.h> | ||
20 | #include <asm/iseries/it_lp_reg_save.h> | 19 | #include <asm/iseries/it_lp_reg_save.h> |
21 | #include <asm/paca.h> | 20 | #include <asm/paca.h> |
22 | 21 | ||
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 483455c5bb02..320c913435cd 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/bitops.h> | 30 | #include <linux/bitops.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/kexec.h> | 32 | #include <linux/kexec.h> |
33 | #include <linux/debugfs.h> | ||
33 | 34 | ||
34 | #include <asm/prom.h> | 35 | #include <asm/prom.h> |
35 | #include <asm/rtas.h> | 36 | #include <asm/rtas.h> |
@@ -952,6 +953,7 @@ static struct ibm_pa_feature { | |||
952 | /* put this back once we know how to test if firmware does 64k IO */ | 953 | /* put this back once we know how to test if firmware does 64k IO */ |
953 | {CPU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, | 954 | {CPU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, |
954 | #endif | 955 | #endif |
956 | {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0}, | ||
955 | }; | 957 | }; |
956 | 958 | ||
957 | static void __init check_cpu_pa_features(unsigned long node) | 959 | static void __init check_cpu_pa_features(unsigned long node) |
@@ -1124,24 +1126,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node, | |||
1124 | tce_alloc_end = *lprop; | 1126 | tce_alloc_end = *lprop; |
1125 | #endif | 1127 | #endif |
1126 | 1128 | ||
1127 | #ifdef CONFIG_PPC_RTAS | ||
1128 | /* To help early debugging via the front panel, we retrieve a minimal | ||
1129 | * set of RTAS infos now if available | ||
1130 | */ | ||
1131 | { | ||
1132 | u64 *basep, *entryp, *sizep; | ||
1133 | |||
1134 | basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL); | ||
1135 | entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL); | ||
1136 | sizep = of_get_flat_dt_prop(node, "linux,rtas-size", NULL); | ||
1137 | if (basep && entryp && sizep) { | ||
1138 | rtas.base = *basep; | ||
1139 | rtas.entry = *entryp; | ||
1140 | rtas.size = *sizep; | ||
1141 | } | ||
1142 | } | ||
1143 | #endif /* CONFIG_PPC_RTAS */ | ||
1144 | |||
1145 | #ifdef CONFIG_KEXEC | 1129 | #ifdef CONFIG_KEXEC |
1146 | lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL); | 1130 | lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL); |
1147 | if (lprop) | 1131 | if (lprop) |
@@ -1326,6 +1310,11 @@ void __init early_init_devtree(void *params) | |||
1326 | /* Setup flat device-tree pointer */ | 1310 | /* Setup flat device-tree pointer */ |
1327 | initial_boot_params = params; | 1311 | initial_boot_params = params; |
1328 | 1312 | ||
1313 | #ifdef CONFIG_PPC_RTAS | ||
1314 | /* Some machines might need RTAS info for debugging, grab it now. */ | ||
1315 | of_scan_flat_dt(early_init_dt_scan_rtas, NULL); | ||
1316 | #endif | ||
1317 | |||
1329 | /* Retrieve various informations from the /chosen node of the | 1318 | /* Retrieve various informations from the /chosen node of the |
1330 | * device-tree, including the platform type, initrd location and | 1319 | * device-tree, including the platform type, initrd location and |
1331 | * size, TCE reserve, and more ... | 1320 | * size, TCE reserve, and more ... |
@@ -2148,3 +2137,27 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) | |||
2148 | } | 2137 | } |
2149 | return NULL; | 2138 | return NULL; |
2150 | } | 2139 | } |
2140 | |||
2141 | #ifdef DEBUG | ||
2142 | static struct debugfs_blob_wrapper flat_dt_blob; | ||
2143 | |||
2144 | static int __init export_flat_device_tree(void) | ||
2145 | { | ||
2146 | struct dentry *d; | ||
2147 | |||
2148 | d = debugfs_create_dir("powerpc", NULL); | ||
2149 | if (!d) | ||
2150 | return 1; | ||
2151 | |||
2152 | flat_dt_blob.data = initial_boot_params; | ||
2153 | flat_dt_blob.size = initial_boot_params->totalsize; | ||
2154 | |||
2155 | d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR, | ||
2156 | d, &flat_dt_blob); | ||
2157 | if (!d) | ||
2158 | return 1; | ||
2159 | |||
2160 | return 0; | ||
2161 | } | ||
2162 | __initcall(export_flat_device_tree); | ||
2163 | #endif | ||
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 17dc79198515..4a4cb5598402 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
@@ -38,16 +38,19 @@ | |||
38 | struct rtas_t rtas = { | 38 | struct rtas_t rtas = { |
39 | .lock = SPIN_LOCK_UNLOCKED | 39 | .lock = SPIN_LOCK_UNLOCKED |
40 | }; | 40 | }; |
41 | EXPORT_SYMBOL(rtas); | ||
41 | 42 | ||
42 | struct rtas_suspend_me_data { | 43 | struct rtas_suspend_me_data { |
43 | long waiting; | 44 | long waiting; |
44 | struct rtas_args *args; | 45 | struct rtas_args *args; |
45 | }; | 46 | }; |
46 | 47 | ||
47 | EXPORT_SYMBOL(rtas); | ||
48 | |||
49 | DEFINE_SPINLOCK(rtas_data_buf_lock); | 48 | DEFINE_SPINLOCK(rtas_data_buf_lock); |
49 | EXPORT_SYMBOL(rtas_data_buf_lock); | ||
50 | |||
50 | char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned; | 51 | char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned; |
52 | EXPORT_SYMBOL(rtas_data_buf); | ||
53 | |||
51 | unsigned long rtas_rmo_buf; | 54 | unsigned long rtas_rmo_buf; |
52 | 55 | ||
53 | /* | 56 | /* |
@@ -106,11 +109,71 @@ static void call_rtas_display_status_delay(char c) | |||
106 | } | 109 | } |
107 | } | 110 | } |
108 | 111 | ||
109 | void __init udbg_init_rtas(void) | 112 | void __init udbg_init_rtas_panel(void) |
110 | { | 113 | { |
111 | udbg_putc = call_rtas_display_status_delay; | 114 | udbg_putc = call_rtas_display_status_delay; |
112 | } | 115 | } |
113 | 116 | ||
117 | #ifdef CONFIG_UDBG_RTAS_CONSOLE | ||
118 | |||
119 | /* If you think you're dying before early_init_dt_scan_rtas() does its | ||
120 | * work, you can hard code the token values for your firmware here and | ||
121 | * hardcode rtas.base/entry etc. | ||
122 | */ | ||
123 | static unsigned int rtas_putchar_token = RTAS_UNKNOWN_SERVICE; | ||
124 | static unsigned int rtas_getchar_token = RTAS_UNKNOWN_SERVICE; | ||
125 | |||
126 | static void udbg_rtascon_putc(char c) | ||
127 | { | ||
128 | int tries; | ||
129 | |||
130 | if (!rtas.base) | ||
131 | return; | ||
132 | |||
133 | /* Add CRs before LFs */ | ||
134 | if (c == '\n') | ||
135 | udbg_rtascon_putc('\r'); | ||
136 | |||
137 | /* if there is more than one character to be displayed, wait a bit */ | ||
138 | for (tries = 0; tries < 16; tries++) { | ||
139 | if (rtas_call(rtas_putchar_token, 1, 1, NULL, c) == 0) | ||
140 | break; | ||
141 | udelay(1000); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | static int udbg_rtascon_getc_poll(void) | ||
146 | { | ||
147 | int c; | ||
148 | |||
149 | if (!rtas.base) | ||
150 | return -1; | ||
151 | |||
152 | if (rtas_call(rtas_getchar_token, 0, 2, &c)) | ||
153 | return -1; | ||
154 | |||
155 | return c; | ||
156 | } | ||
157 | |||
158 | static int udbg_rtascon_getc(void) | ||
159 | { | ||
160 | int c; | ||
161 | |||
162 | while ((c = udbg_rtascon_getc_poll()) == -1) | ||
163 | ; | ||
164 | |||
165 | return c; | ||
166 | } | ||
167 | |||
168 | |||
169 | void __init udbg_init_rtas_console(void) | ||
170 | { | ||
171 | udbg_putc = udbg_rtascon_putc; | ||
172 | udbg_getc = udbg_rtascon_getc; | ||
173 | udbg_getc_poll = udbg_rtascon_getc_poll; | ||
174 | } | ||
175 | #endif /* CONFIG_UDBG_RTAS_CONSOLE */ | ||
176 | |||
114 | void rtas_progress(char *s, unsigned short hex) | 177 | void rtas_progress(char *s, unsigned short hex) |
115 | { | 178 | { |
116 | struct device_node *root; | 179 | struct device_node *root; |
@@ -236,6 +299,7 @@ int rtas_token(const char *service) | |||
236 | tokp = (int *) get_property(rtas.dev, service, NULL); | 299 | tokp = (int *) get_property(rtas.dev, service, NULL); |
237 | return tokp ? *tokp : RTAS_UNKNOWN_SERVICE; | 300 | return tokp ? *tokp : RTAS_UNKNOWN_SERVICE; |
238 | } | 301 | } |
302 | EXPORT_SYMBOL(rtas_token); | ||
239 | 303 | ||
240 | #ifdef CONFIG_RTAS_ERROR_LOGGING | 304 | #ifdef CONFIG_RTAS_ERROR_LOGGING |
241 | /* | 305 | /* |
@@ -328,7 +392,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) | |||
328 | char *buff_copy = NULL; | 392 | char *buff_copy = NULL; |
329 | int ret; | 393 | int ret; |
330 | 394 | ||
331 | if (token == RTAS_UNKNOWN_SERVICE) | 395 | if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE) |
332 | return -1; | 396 | return -1; |
333 | 397 | ||
334 | /* Gotta do something different here, use global lock for now... */ | 398 | /* Gotta do something different here, use global lock for now... */ |
@@ -369,6 +433,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) | |||
369 | } | 433 | } |
370 | return ret; | 434 | return ret; |
371 | } | 435 | } |
436 | EXPORT_SYMBOL(rtas_call); | ||
372 | 437 | ||
373 | /* For RTAS_BUSY (-2), delay for 1 millisecond. For an extended busy status | 438 | /* For RTAS_BUSY (-2), delay for 1 millisecond. For an extended busy status |
374 | * code of 990n, perform the hinted delay of 10^n (last digit) milliseconds. | 439 | * code of 990n, perform the hinted delay of 10^n (last digit) milliseconds. |
@@ -388,6 +453,7 @@ unsigned int rtas_busy_delay_time(int status) | |||
388 | 453 | ||
389 | return ms; | 454 | return ms; |
390 | } | 455 | } |
456 | EXPORT_SYMBOL(rtas_busy_delay_time); | ||
391 | 457 | ||
392 | /* For an RTAS busy status code, perform the hinted delay. */ | 458 | /* For an RTAS busy status code, perform the hinted delay. */ |
393 | unsigned int rtas_busy_delay(int status) | 459 | unsigned int rtas_busy_delay(int status) |
@@ -401,6 +467,7 @@ unsigned int rtas_busy_delay(int status) | |||
401 | 467 | ||
402 | return ms; | 468 | return ms; |
403 | } | 469 | } |
470 | EXPORT_SYMBOL(rtas_busy_delay); | ||
404 | 471 | ||
405 | int rtas_error_rc(int rtas_rc) | 472 | int rtas_error_rc(int rtas_rc) |
406 | { | 473 | { |
@@ -446,6 +513,7 @@ int rtas_get_power_level(int powerdomain, int *level) | |||
446 | return rtas_error_rc(rc); | 513 | return rtas_error_rc(rc); |
447 | return rc; | 514 | return rc; |
448 | } | 515 | } |
516 | EXPORT_SYMBOL(rtas_get_power_level); | ||
449 | 517 | ||
450 | int rtas_set_power_level(int powerdomain, int level, int *setlevel) | 518 | int rtas_set_power_level(int powerdomain, int level, int *setlevel) |
451 | { | 519 | { |
@@ -463,6 +531,7 @@ int rtas_set_power_level(int powerdomain, int level, int *setlevel) | |||
463 | return rtas_error_rc(rc); | 531 | return rtas_error_rc(rc); |
464 | return rc; | 532 | return rc; |
465 | } | 533 | } |
534 | EXPORT_SYMBOL(rtas_set_power_level); | ||
466 | 535 | ||
467 | int rtas_get_sensor(int sensor, int index, int *state) | 536 | int rtas_get_sensor(int sensor, int index, int *state) |
468 | { | 537 | { |
@@ -480,6 +549,7 @@ int rtas_get_sensor(int sensor, int index, int *state) | |||
480 | return rtas_error_rc(rc); | 549 | return rtas_error_rc(rc); |
481 | return rc; | 550 | return rc; |
482 | } | 551 | } |
552 | EXPORT_SYMBOL(rtas_get_sensor); | ||
483 | 553 | ||
484 | int rtas_set_indicator(int indicator, int index, int new_value) | 554 | int rtas_set_indicator(int indicator, int index, int new_value) |
485 | { | 555 | { |
@@ -497,6 +567,7 @@ int rtas_set_indicator(int indicator, int index, int new_value) | |||
497 | return rtas_error_rc(rc); | 567 | return rtas_error_rc(rc); |
498 | return rc; | 568 | return rc; |
499 | } | 569 | } |
570 | EXPORT_SYMBOL(rtas_set_indicator); | ||
500 | 571 | ||
501 | void rtas_restart(char *cmd) | 572 | void rtas_restart(char *cmd) |
502 | { | 573 | { |
@@ -791,14 +862,34 @@ void __init rtas_initialize(void) | |||
791 | #endif | 862 | #endif |
792 | } | 863 | } |
793 | 864 | ||
865 | int __init early_init_dt_scan_rtas(unsigned long node, | ||
866 | const char *uname, int depth, void *data) | ||
867 | { | ||
868 | u32 *basep, *entryp, *sizep; | ||
794 | 869 | ||
795 | EXPORT_SYMBOL(rtas_token); | 870 | if (depth != 1 || strcmp(uname, "rtas") != 0) |
796 | EXPORT_SYMBOL(rtas_call); | 871 | return 0; |
797 | EXPORT_SYMBOL(rtas_data_buf); | 872 | |
798 | EXPORT_SYMBOL(rtas_data_buf_lock); | 873 | basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL); |
799 | EXPORT_SYMBOL(rtas_busy_delay_time); | 874 | entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL); |
800 | EXPORT_SYMBOL(rtas_busy_delay); | 875 | sizep = of_get_flat_dt_prop(node, "rtas-size", NULL); |
801 | EXPORT_SYMBOL(rtas_get_sensor); | 876 | |
802 | EXPORT_SYMBOL(rtas_get_power_level); | 877 | if (basep && entryp && sizep) { |
803 | EXPORT_SYMBOL(rtas_set_power_level); | 878 | rtas.base = *basep; |
804 | EXPORT_SYMBOL(rtas_set_indicator); | 879 | rtas.entry = *entryp; |
880 | rtas.size = *sizep; | ||
881 | } | ||
882 | |||
883 | #ifdef CONFIG_UDBG_RTAS_CONSOLE | ||
884 | basep = of_get_flat_dt_prop(node, "put-term-char", NULL); | ||
885 | if (basep) | ||
886 | rtas_putchar_token = *basep; | ||
887 | |||
888 | basep = of_get_flat_dt_prop(node, "get-term-char", NULL); | ||
889 | if (basep) | ||
890 | rtas_getchar_token = *basep; | ||
891 | #endif | ||
892 | |||
893 | /* break now */ | ||
894 | return 1; | ||
895 | } | ||
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 78f3a5fd43f6..175539c9afa0 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -149,6 +149,13 @@ early_param("smt-enabled", early_smt_enabled); | |||
149 | #define check_smt_enabled() | 149 | #define check_smt_enabled() |
150 | #endif /* CONFIG_SMP */ | 150 | #endif /* CONFIG_SMP */ |
151 | 151 | ||
152 | /* Put the paca pointer into r13 and SPRG3 */ | ||
153 | void __init setup_paca(int cpu) | ||
154 | { | ||
155 | local_paca = &paca[cpu]; | ||
156 | mtspr(SPRN_SPRG3, local_paca); | ||
157 | } | ||
158 | |||
152 | /* | 159 | /* |
153 | * Early initialization entry point. This is called by head.S | 160 | * Early initialization entry point. This is called by head.S |
154 | * with MMU translation disabled. We rely on the "feature" of | 161 | * with MMU translation disabled. We rely on the "feature" of |
@@ -170,6 +177,9 @@ early_param("smt-enabled", early_smt_enabled); | |||
170 | 177 | ||
171 | void __init early_setup(unsigned long dt_ptr) | 178 | void __init early_setup(unsigned long dt_ptr) |
172 | { | 179 | { |
180 | /* Assume we're on cpu 0 for now. Don't write to the paca yet! */ | ||
181 | setup_paca(0); | ||
182 | |||
173 | /* Enable early debugging if any specified (see udbg.h) */ | 183 | /* Enable early debugging if any specified (see udbg.h) */ |
174 | udbg_early_init(); | 184 | udbg_early_init(); |
175 | 185 | ||
@@ -183,7 +193,7 @@ void __init early_setup(unsigned long dt_ptr) | |||
183 | early_init_devtree(__va(dt_ptr)); | 193 | early_init_devtree(__va(dt_ptr)); |
184 | 194 | ||
185 | /* Now we know the logical id of our boot cpu, setup the paca. */ | 195 | /* Now we know the logical id of our boot cpu, setup the paca. */ |
186 | setup_boot_paca(); | 196 | setup_paca(boot_cpuid); |
187 | 197 | ||
188 | /* Fix up paca fields required for the boot cpu */ | 198 | /* Fix up paca fields required for the boot cpu */ |
189 | get_paca()->cpu_start = 1; | 199 | get_paca()->cpu_start = 1; |
@@ -350,19 +360,11 @@ void __init setup_system(void) | |||
350 | */ | 360 | */ |
351 | unflatten_device_tree(); | 361 | unflatten_device_tree(); |
352 | 362 | ||
353 | #ifdef CONFIG_KEXEC | ||
354 | kexec_setup(); /* requires unflattened device tree. */ | ||
355 | #endif | ||
356 | |||
357 | /* | 363 | /* |
358 | * Fill the ppc64_caches & systemcfg structures with informations | 364 | * Fill the ppc64_caches & systemcfg structures with informations |
359 | * retrieved from the device-tree. Need to be called before | 365 | * retrieved from the device-tree. Need to be called before |
360 | * finish_device_tree() since the later requires some of the | 366 | * finish_device_tree() since the later requires some of the |
361 | * informations filled up here to properly parse the interrupt | 367 | * informations filled up here to properly parse the interrupt tree. |
362 | * tree. | ||
363 | * It also sets up the cache line sizes which allows to call | ||
364 | * routines like flush_icache_range (used by the hash init | ||
365 | * later on). | ||
366 | */ | 368 | */ |
367 | initialize_cache_info(); | 369 | initialize_cache_info(); |
368 | 370 | ||
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 52f5659534f4..fa6bd97b6b9d 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -52,9 +52,13 @@ | |||
52 | #include <asm/firmware.h> | 52 | #include <asm/firmware.h> |
53 | #include <asm/processor.h> | 53 | #include <asm/processor.h> |
54 | #endif | 54 | #endif |
55 | #include <asm/kexec.h> | ||
55 | 56 | ||
56 | #ifdef CONFIG_PPC64 /* XXX */ | 57 | #ifdef CONFIG_PPC64 /* XXX */ |
57 | #define _IO_BASE pci_io_base | 58 | #define _IO_BASE pci_io_base |
59 | #ifdef CONFIG_KEXEC | ||
60 | cpumask_t cpus_in_sr = CPU_MASK_NONE; | ||
61 | #endif | ||
58 | #endif | 62 | #endif |
59 | 63 | ||
60 | #ifdef CONFIG_DEBUGGER | 64 | #ifdef CONFIG_DEBUGGER |
@@ -97,7 +101,7 @@ static DEFINE_SPINLOCK(die_lock); | |||
97 | 101 | ||
98 | int die(const char *str, struct pt_regs *regs, long err) | 102 | int die(const char *str, struct pt_regs *regs, long err) |
99 | { | 103 | { |
100 | static int die_counter, crash_dump_start = 0; | 104 | static int die_counter; |
101 | 105 | ||
102 | if (debugger(regs)) | 106 | if (debugger(regs)) |
103 | return 1; | 107 | return 1; |
@@ -137,21 +141,12 @@ int die(const char *str, struct pt_regs *regs, long err) | |||
137 | print_modules(); | 141 | print_modules(); |
138 | show_regs(regs); | 142 | show_regs(regs); |
139 | bust_spinlocks(0); | 143 | bust_spinlocks(0); |
144 | spin_unlock_irq(&die_lock); | ||
140 | 145 | ||
141 | if (!crash_dump_start && kexec_should_crash(current)) { | 146 | if (kexec_should_crash(current) || |
142 | crash_dump_start = 1; | 147 | kexec_sr_activated(smp_processor_id())) |
143 | spin_unlock_irq(&die_lock); | ||
144 | crash_kexec(regs); | 148 | crash_kexec(regs); |
145 | /* NOTREACHED */ | 149 | crash_kexec_secondary(regs); |
146 | } | ||
147 | spin_unlock_irq(&die_lock); | ||
148 | if (crash_dump_start) | ||
149 | /* | ||
150 | * Only for soft-reset: Other CPUs will be responded to an IPI | ||
151 | * sent by first kexec CPU. | ||
152 | */ | ||
153 | for(;;) | ||
154 | ; | ||
155 | 150 | ||
156 | if (in_interrupt()) | 151 | if (in_interrupt()) |
157 | panic("Fatal exception in interrupt"); | 152 | panic("Fatal exception in interrupt"); |
@@ -215,6 +210,10 @@ void system_reset_exception(struct pt_regs *regs) | |||
215 | return; | 210 | return; |
216 | } | 211 | } |
217 | 212 | ||
213 | #ifdef CONFIG_KEXEC | ||
214 | cpu_set(smp_processor_id(), cpus_in_sr); | ||
215 | #endif | ||
216 | |||
218 | die("System Reset", regs, SIGABRT); | 217 | die("System Reset", regs, SIGABRT); |
219 | 218 | ||
220 | /* Must die if the interrupt is not recoverable */ | 219 | /* Must die if the interrupt is not recoverable */ |
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c index 67d9fd9ae2b5..759afd5e0d8a 100644 --- a/arch/powerpc/kernel/udbg.c +++ b/arch/powerpc/kernel/udbg.c | |||
@@ -34,9 +34,12 @@ void __init udbg_early_init(void) | |||
34 | #elif defined(CONFIG_PPC_EARLY_DEBUG_G5) | 34 | #elif defined(CONFIG_PPC_EARLY_DEBUG_G5) |
35 | /* For use on Apple G5 machines */ | 35 | /* For use on Apple G5 machines */ |
36 | udbg_init_pmac_realmode(); | 36 | udbg_init_pmac_realmode(); |
37 | #elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS) | 37 | #elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL) |
38 | /* RTAS panel debug */ | 38 | /* RTAS panel debug */ |
39 | udbg_init_rtas(); | 39 | udbg_init_rtas_panel(); |
40 | #elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE) | ||
41 | /* RTAS console debug */ | ||
42 | udbg_init_rtas_console(); | ||
40 | #elif defined(CONFIG_PPC_EARLY_DEBUG_MAPLE) | 43 | #elif defined(CONFIG_PPC_EARLY_DEBUG_MAPLE) |
41 | /* Maple real mode debug */ | 44 | /* Maple real mode debug */ |
42 | udbg_init_maple_realmode(); | 45 | udbg_init_maple_realmode(); |