aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-01-09 13:03:44 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-09 13:03:44 -0500
commit6150c32589d1976ca8a5c987df951088c05a7542 (patch)
tree94073696576323ff966e365d8c47b8ecd8372f97 /arch/powerpc/kernel
parent44637a12f80b80157d9c1bc5b7d6ef09c9e05713 (diff)
parentbe42d5fa3772241b8ecebd443f1fb36247959c54 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/Makefile22
-rw-r--r--arch/powerpc/kernel/asm-offsets.c6
-rw-r--r--arch/powerpc/kernel/btext.c136
-rw-r--r--arch/powerpc/kernel/cputable.c106
-rw-r--r--arch/powerpc/kernel/crash.c264
-rw-r--r--arch/powerpc/kernel/crash_dump.c109
-rw-r--r--arch/powerpc/kernel/dma_64.c9
-rw-r--r--arch/powerpc/kernel/entry_32.S167
-rw-r--r--arch/powerpc/kernel/entry_64.S218
-rw-r--r--arch/powerpc/kernel/head_32.S56
-rw-r--r--arch/powerpc/kernel/head_64.S41
-rw-r--r--arch/powerpc/kernel/ibmebus.c396
-rw-r--r--arch/powerpc/kernel/irq.c81
-rw-r--r--arch/powerpc/kernel/legacy_serial.c557
-rw-r--r--arch/powerpc/kernel/lparmap.c12
-rw-r--r--arch/powerpc/kernel/machine_kexec.c67
-rw-r--r--arch/powerpc/kernel/machine_kexec_32.c65
-rw-r--r--arch/powerpc/kernel/machine_kexec_64.c43
-rw-r--r--arch/powerpc/kernel/misc_32.S113
-rw-r--r--arch/powerpc/kernel/nvram_64.c106
-rw-r--r--arch/powerpc/kernel/paca.c11
-rw-r--r--arch/powerpc/kernel/pci_64.c87
-rw-r--r--arch/powerpc/kernel/pmc.c5
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c5
-rw-r--r--arch/powerpc/kernel/prom.c468
-rw-r--r--arch/powerpc/kernel/prom_init.c60
-rw-r--r--arch/powerpc/kernel/prom_parse.c547
-rw-r--r--arch/powerpc/kernel/rtas_pci.c49
-rw-r--r--arch/powerpc/kernel/setup-common.c129
-rw-r--r--arch/powerpc/kernel/setup_32.c34
-rw-r--r--arch/powerpc/kernel/setup_64.c207
-rw-r--r--arch/powerpc/kernel/signal_32.c68
-rw-r--r--arch/powerpc/kernel/signal_64.c23
-rw-r--r--arch/powerpc/kernel/smp.c29
-rw-r--r--arch/powerpc/kernel/syscalls.c28
-rw-r--r--arch/powerpc/kernel/systbl.S14
-rw-r--r--arch/powerpc/kernel/time.c4
-rw-r--r--arch/powerpc/kernel/traps.c25
-rw-r--r--arch/powerpc/kernel/udbg.c27
-rw-r--r--arch/powerpc/kernel/udbg_16550.c69
-rw-r--r--arch/powerpc/kernel/udbg_scc.c135
41 files changed, 3104 insertions, 1494 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 9ed551b6c172..6e03b595b6c8 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -17,11 +17,11 @@ obj-y += vdso32/
17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ 17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
18 signal_64.o ptrace32.o systbl.o \ 18 signal_64.o ptrace32.o systbl.o \
19 paca.o ioctl32.o cpu_setup_power4.o \ 19 paca.o ioctl32.o cpu_setup_power4.o \
20 firmware.o sysfs.o udbg.o idle_64.o 20 firmware.o sysfs.o idle_64.o
21obj-$(CONFIG_PPC64) += vdso64/ 21obj-$(CONFIG_PPC64) += vdso64/
22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o 22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
23obj-$(CONFIG_POWER4) += idle_power4.o 23obj-$(CONFIG_POWER4) += idle_power4.o
24obj-$(CONFIG_PPC_OF) += of_device.o 24obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o
25procfs-$(CONFIG_PPC64) := proc_ppc64.o 25procfs-$(CONFIG_PPC64) := proc_ppc64.o
26obj-$(CONFIG_PROC_FS) += $(procfs-y) 26obj-$(CONFIG_PROC_FS) += $(procfs-y)
27rtaspci-$(CONFIG_PPC64) := rtas_pci.o 27rtaspci-$(CONFIG_PPC64) := rtas_pci.o
@@ -30,12 +30,10 @@ obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
30obj-$(CONFIG_RTAS_PROC) += rtas-proc.o 30obj-$(CONFIG_RTAS_PROC) += rtas-proc.o
31obj-$(CONFIG_LPARCFG) += lparcfg.o 31obj-$(CONFIG_LPARCFG) += lparcfg.o
32obj-$(CONFIG_IBMVIO) += vio.o 32obj-$(CONFIG_IBMVIO) += vio.o
33obj-$(CONFIG_IBMEBUS) += ibmebus.o
33obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o 34obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
34obj-$(CONFIG_PPC_PSERIES) += udbg_16550.o
35obj-$(CONFIG_PPC_MAPLE) += udbg_16550.o
36udbgscc-$(CONFIG_PPC64) := udbg_scc.o
37obj-$(CONFIG_PPC_PMAC) += $(udbgscc-y)
38obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o 35obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o
36obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
39 37
40ifeq ($(CONFIG_PPC_MERGE),y) 38ifeq ($(CONFIG_PPC_MERGE),y)
41 39
@@ -48,25 +46,25 @@ extra-$(CONFIG_8xx) := head_8xx.o
48extra-y += vmlinux.lds 46extra-y += vmlinux.lds
49 47
50obj-y += process.o init_task.o time.o \ 48obj-y += process.o init_task.o time.o \
51 prom.o traps.o setup-common.o 49 prom.o traps.o setup-common.o udbg.o
52obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o systbl.o 50obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o systbl.o
53obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o 51obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o
54obj-$(CONFIG_PPC_OF) += prom_init.o 52obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
55obj-$(CONFIG_MODULES) += ppc_ksyms.o 53obj-$(CONFIG_MODULES) += ppc_ksyms.o
56obj-$(CONFIG_BOOTX_TEXT) += btext.o 54obj-$(CONFIG_BOOTX_TEXT) += btext.o
57obj-$(CONFIG_6xx) += idle_6xx.o 55obj-$(CONFIG_6xx) += idle_6xx.o
58obj-$(CONFIG_SMP) += smp.o 56obj-$(CONFIG_SMP) += smp.o
59obj-$(CONFIG_KPROBES) += kprobes.o 57obj-$(CONFIG_KPROBES) += kprobes.o
60 58obj-$(CONFIG_SERIAL_8250) += legacy_serial.o udbg_16550.o
61module-$(CONFIG_PPC64) += module_64.o 59module-$(CONFIG_PPC64) += module_64.o
62obj-$(CONFIG_MODULES) += $(module-y) 60obj-$(CONFIG_MODULES) += $(module-y)
63 61
64pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \ 62pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \
65 pci_direct_iommu.o iomap.o 63 pci_direct_iommu.o iomap.o
66obj-$(CONFIG_PCI) += $(pci64-y) 64obj-$(CONFIG_PCI) += $(pci64-y)
67 65kexec-$(CONFIG_PPC64) := machine_kexec_64.o
68kexec64-$(CONFIG_PPC64) += machine_kexec_64.o 66kexec-$(CONFIG_PPC32) := machine_kexec_32.o
69obj-$(CONFIG_KEXEC) += $(kexec64-y) 67obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o $(kexec-y)
70 68
71ifeq ($(CONFIG_PPC_ISERIES),y) 69ifeq ($(CONFIG_PPC_ISERIES),y)
72$(obj)/head_64.o: $(obj)/lparmap.s 70$(obj)/head_64.o: $(obj)/lparmap.s
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 91538d2445bf..56399c5c931a 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -92,9 +92,9 @@ int main(void)
92 92
93 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); 93 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
94 DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); 94 DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
95 DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror)); 95 DEFINE(TI_SIGFRAME, offsetof(struct thread_info, nvgprs_frame));
96#ifdef CONFIG_PPC32
97 DEFINE(TI_TASK, offsetof(struct thread_info, task)); 96 DEFINE(TI_TASK, offsetof(struct thread_info, task));
97#ifdef CONFIG_PPC32
98 DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain)); 98 DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
99 DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); 99 DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
100#endif /* CONFIG_PPC32 */ 100#endif /* CONFIG_PPC32 */
@@ -131,11 +131,9 @@ int main(void)
131 DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas)); 131 DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas));
132 DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas)); 132 DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas));
133#endif /* CONFIG_HUGETLB_PAGE */ 133#endif /* CONFIG_HUGETLB_PAGE */
134 DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr));
135 DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen)); 134 DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
136 DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc)); 135 DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
137 DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb)); 136 DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb));
138 DEFINE(PACA_EXDSI, offsetof(struct paca_struct, exdsi));
139 DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp)); 137 DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
140 DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca)); 138 DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca));
141 DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); 139 DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c
index bdfba92b2b38..6223d39177cb 100644
--- a/arch/powerpc/kernel/btext.c
+++ b/arch/powerpc/kernel/btext.c
@@ -31,15 +31,18 @@ static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb);
31static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb); 31static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb);
32static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb); 32static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb);
33 33
34static int g_loc_X; 34#define __force_data __attribute__((__section__(".data")))
35static int g_loc_Y;
36static int g_max_loc_X;
37static int g_max_loc_Y;
38 35
39static int dispDeviceRowBytes; 36static int g_loc_X __force_data;
40static int dispDeviceDepth; 37static int g_loc_Y __force_data;
41static int dispDeviceRect[4]; 38static int g_max_loc_X __force_data;
42static unsigned char *dispDeviceBase, *logicalDisplayBase; 39static int g_max_loc_Y __force_data;
40
41static int dispDeviceRowBytes __force_data;
42static int dispDeviceDepth __force_data;
43static int dispDeviceRect[4] __force_data;
44static unsigned char *dispDeviceBase __force_data;
45static unsigned char *logicalDisplayBase __force_data;
43 46
44unsigned long disp_BAT[2] __initdata = {0, 0}; 47unsigned long disp_BAT[2] __initdata = {0, 0};
45 48
@@ -47,7 +50,7 @@ unsigned long disp_BAT[2] __initdata = {0, 0};
47 50
48static unsigned char vga_font[cmapsz]; 51static unsigned char vga_font[cmapsz];
49 52
50int boot_text_mapped; 53int boot_text_mapped __force_data = 0;
51int force_printk_to_btext = 0; 54int force_printk_to_btext = 0;
52 55
53#ifdef CONFIG_PPC32 56#ifdef CONFIG_PPC32
@@ -57,7 +60,7 @@ int force_printk_to_btext = 0;
57 * 60 *
58 * The display is mapped to virtual address 0xD0000000, rather 61 * The display is mapped to virtual address 0xD0000000, rather
59 * than 1:1, because some some CHRP machines put the frame buffer 62 * than 1:1, because some some CHRP machines put the frame buffer
60 * in the region starting at 0xC0000000 (KERNELBASE). 63 * in the region starting at 0xC0000000 (PAGE_OFFSET).
61 * This mapping is temporary and will disappear as soon as the 64 * This mapping is temporary and will disappear as soon as the
62 * setup done by MMU_Init() is applied. 65 * setup done by MMU_Init() is applied.
63 * 66 *
@@ -66,10 +69,9 @@ int force_printk_to_btext = 0;
66 * is really badly aligned, but I didn't encounter this case 69 * is really badly aligned, but I didn't encounter this case
67 * yet. 70 * yet.
68 */ 71 */
69void __init 72void __init btext_prepare_BAT(void)
70btext_prepare_BAT(void)
71{ 73{
72 unsigned long vaddr = KERNELBASE + 0x10000000; 74 unsigned long vaddr = PAGE_OFFSET + 0x10000000;
73 unsigned long addr; 75 unsigned long addr;
74 unsigned long lowbits; 76 unsigned long lowbits;
75 77
@@ -95,12 +97,13 @@ btext_prepare_BAT(void)
95} 97}
96#endif 98#endif
97 99
98/* This function will enable the early boot text when doing OF booting. This 100
99 * way, xmon output should work too 101/* This function can be used to enable the early boot text when doing
102 * OF booting or within bootx init. It must be followed by a btext_unmap()
103 * call before the logical address becomes unuseable
100 */ 104 */
101void __init 105void __init btext_setup_display(int width, int height, int depth, int pitch,
102btext_setup_display(int width, int height, int depth, int pitch, 106 unsigned long address)
103 unsigned long address)
104{ 107{
105 g_loc_X = 0; 108 g_loc_X = 0;
106 g_loc_Y = 0; 109 g_loc_Y = 0;
@@ -116,6 +119,11 @@ btext_setup_display(int width, int height, int depth, int pitch,
116 boot_text_mapped = 1; 119 boot_text_mapped = 1;
117} 120}
118 121
122void __init btext_unmap(void)
123{
124 boot_text_mapped = 0;
125}
126
119/* Here's a small text engine to use during early boot 127/* Here's a small text engine to use during early boot
120 * or for debugging purposes 128 * or for debugging purposes
121 * 129 *
@@ -127,7 +135,7 @@ btext_setup_display(int width, int height, int depth, int pitch,
127 * changes. 135 * changes.
128 */ 136 */
129 137
130void map_boot_text(void) 138static void map_boot_text(void)
131{ 139{
132 unsigned long base, offset, size; 140 unsigned long base, offset, size;
133 unsigned char *vbase; 141 unsigned char *vbase;
@@ -175,8 +183,9 @@ int btext_initialize(struct device_node *np)
175 if (prop) 183 if (prop)
176 address = *prop; 184 address = *prop;
177 185
178 /* FIXME: Add support for PCI reg properties */ 186 /* FIXME: Add support for PCI reg properties. Right now, only
179 187 * reliable on macs
188 */
180 if (address == 0) 189 if (address == 0)
181 return -EINVAL; 190 return -EINVAL;
182 191
@@ -184,7 +193,6 @@ int btext_initialize(struct device_node *np)
184 g_loc_Y = 0; 193 g_loc_Y = 0;
185 g_max_loc_X = width / 8; 194 g_max_loc_X = width / 8;
186 g_max_loc_Y = height / 16; 195 g_max_loc_Y = height / 16;
187 logicalDisplayBase = (unsigned char *)address;
188 dispDeviceBase = (unsigned char *)address; 196 dispDeviceBase = (unsigned char *)address;
189 dispDeviceRowBytes = pitch; 197 dispDeviceRowBytes = pitch;
190 dispDeviceDepth = depth; 198 dispDeviceDepth = depth;
@@ -197,14 +205,12 @@ int btext_initialize(struct device_node *np)
197 return 0; 205 return 0;
198} 206}
199 207
200void __init init_boot_display(void) 208int __init btext_find_display(int allow_nonstdout)
201{ 209{
202 char *name; 210 char *name;
203 struct device_node *np = NULL; 211 struct device_node *np = NULL;
204 int rc = -ENODEV; 212 int rc = -ENODEV;
205 213
206 printk("trying to initialize btext ...\n");
207
208 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); 214 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
209 if (name != NULL) { 215 if (name != NULL) {
210 np = of_find_node_by_path(name); 216 np = of_find_node_by_path(name);
@@ -218,8 +224,8 @@ void __init init_boot_display(void)
218 } 224 }
219 if (np) 225 if (np)
220 rc = btext_initialize(np); 226 rc = btext_initialize(np);
221 if (rc == 0) 227 if (rc == 0 || !allow_nonstdout)
222 return; 228 return rc;
223 229
224 for (np = NULL; (np = of_find_node_by_type(np, "display"));) { 230 for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
225 if (get_property(np, "linux,opened", NULL)) { 231 if (get_property(np, "linux,opened", NULL)) {
@@ -228,8 +234,9 @@ void __init init_boot_display(void)
228 printk("result: %d\n", rc); 234 printk("result: %d\n", rc);
229 } 235 }
230 if (rc == 0) 236 if (rc == 0)
231 return; 237 break;
232 } 238 }
239 return rc;
233} 240}
234 241
235/* Calc the base address of a given point (x,y) */ 242/* Calc the base address of a given point (x,y) */
@@ -277,44 +284,83 @@ EXPORT_SYMBOL(btext_update_display);
277 284
278void btext_clearscreen(void) 285void btext_clearscreen(void)
279{ 286{
280 unsigned long *base = (unsigned long *)calc_base(0, 0); 287 unsigned int *base = (unsigned int *)calc_base(0, 0);
281 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) * 288 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
282 (dispDeviceDepth >> 3)) >> 3; 289 (dispDeviceDepth >> 3)) >> 2;
283 int i,j; 290 int i,j;
284 291
285 for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++) 292 for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
286 { 293 {
287 unsigned long *ptr = base; 294 unsigned int *ptr = base;
288 for(j=width; j; --j) 295 for(j=width; j; --j)
289 *(ptr++) = 0; 296 *(ptr++) = 0;
290 base += (dispDeviceRowBytes >> 3); 297 base += (dispDeviceRowBytes >> 2);
291 } 298 }
292} 299}
293 300
301void btext_flushscreen(void)
302{
303 unsigned int *base = (unsigned int *)calc_base(0, 0);
304 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
305 (dispDeviceDepth >> 3)) >> 2;
306 int i,j;
307
308 for (i=0; i < (dispDeviceRect[3] - dispDeviceRect[1]); i++)
309 {
310 unsigned int *ptr = base;
311 for(j = width; j > 0; j -= 8) {
312 __asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
313 ptr += 8;
314 }
315 base += (dispDeviceRowBytes >> 2);
316 }
317 __asm__ __volatile__ ("sync" ::: "memory");
318}
319
320void btext_flushline(void)
321{
322 unsigned int *base = (unsigned int *)calc_base(0, g_loc_Y << 4);
323 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
324 (dispDeviceDepth >> 3)) >> 2;
325 int i,j;
326
327 for (i=0; i < 16; i++)
328 {
329 unsigned int *ptr = base;
330 for(j = width; j > 0; j -= 8) {
331 __asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
332 ptr += 8;
333 }
334 base += (dispDeviceRowBytes >> 2);
335 }
336 __asm__ __volatile__ ("sync" ::: "memory");
337}
338
339
294#ifndef NO_SCROLL 340#ifndef NO_SCROLL
295static void scrollscreen(void) 341static void scrollscreen(void)
296{ 342{
297 unsigned long *src = (unsigned long *)calc_base(0,16); 343 unsigned int *src = (unsigned int *)calc_base(0,16);
298 unsigned long *dst = (unsigned long *)calc_base(0,0); 344 unsigned int *dst = (unsigned int *)calc_base(0,0);
299 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) * 345 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
300 (dispDeviceDepth >> 3)) >> 3; 346 (dispDeviceDepth >> 3)) >> 2;
301 int i,j; 347 int i,j;
302 348
303 for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++) 349 for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
304 { 350 {
305 unsigned long *src_ptr = src; 351 unsigned int *src_ptr = src;
306 unsigned long *dst_ptr = dst; 352 unsigned int *dst_ptr = dst;
307 for(j=width; j; --j) 353 for(j=width; j; --j)
308 *(dst_ptr++) = *(src_ptr++); 354 *(dst_ptr++) = *(src_ptr++);
309 src += (dispDeviceRowBytes >> 3); 355 src += (dispDeviceRowBytes >> 2);
310 dst += (dispDeviceRowBytes >> 3); 356 dst += (dispDeviceRowBytes >> 2);
311 } 357 }
312 for (i=0; i<16; i++) 358 for (i=0; i<16; i++)
313 { 359 {
314 unsigned long *dst_ptr = dst; 360 unsigned int *dst_ptr = dst;
315 for(j=width; j; --j) 361 for(j=width; j; --j)
316 *(dst_ptr++) = 0; 362 *(dst_ptr++) = 0;
317 dst += (dispDeviceRowBytes >> 3); 363 dst += (dispDeviceRowBytes >> 2);
318 } 364 }
319} 365}
320#endif /* ndef NO_SCROLL */ 366#endif /* ndef NO_SCROLL */
@@ -377,6 +423,14 @@ void btext_drawstring(const char *c)
377 btext_drawchar(*c++); 423 btext_drawchar(*c++);
378} 424}
379 425
426void btext_drawtext(const char *c, unsigned int len)
427{
428 if (!boot_text_mapped)
429 return;
430 while (len--)
431 btext_drawchar(*c++);
432}
433
380void btext_drawhex(unsigned long v) 434void btext_drawhex(unsigned long v)
381{ 435{
382 char *hex_table = "0123456789abcdef"; 436 char *hex_table = "0123456789abcdef";
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 1d85cedbbb7b..43c74a6b07b1 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -78,10 +78,8 @@ struct cpu_spec cpu_specs[] = {
78 .dcache_bsize = 128, 78 .dcache_bsize = 128,
79 .num_pmcs = 8, 79 .num_pmcs = 8,
80 .cpu_setup = __setup_cpu_power3, 80 .cpu_setup = __setup_cpu_power3,
81#ifdef CONFIG_OPROFILE
82 .oprofile_cpu_type = "ppc64/power3", 81 .oprofile_cpu_type = "ppc64/power3",
83 .oprofile_model = &op_model_rs64, 82 .oprofile_type = RS64,
84#endif
85 }, 83 },
86 { /* Power3+ */ 84 { /* Power3+ */
87 .pvr_mask = 0xffff0000, 85 .pvr_mask = 0xffff0000,
@@ -93,10 +91,8 @@ struct cpu_spec cpu_specs[] = {
93 .dcache_bsize = 128, 91 .dcache_bsize = 128,
94 .num_pmcs = 8, 92 .num_pmcs = 8,
95 .cpu_setup = __setup_cpu_power3, 93 .cpu_setup = __setup_cpu_power3,
96#ifdef CONFIG_OPROFILE
97 .oprofile_cpu_type = "ppc64/power3", 94 .oprofile_cpu_type = "ppc64/power3",
98 .oprofile_model = &op_model_rs64, 95 .oprofile_type = RS64,
99#endif
100 }, 96 },
101 { /* Northstar */ 97 { /* Northstar */
102 .pvr_mask = 0xffff0000, 98 .pvr_mask = 0xffff0000,
@@ -108,10 +104,8 @@ struct cpu_spec cpu_specs[] = {
108 .dcache_bsize = 128, 104 .dcache_bsize = 128,
109 .num_pmcs = 8, 105 .num_pmcs = 8,
110 .cpu_setup = __setup_cpu_power3, 106 .cpu_setup = __setup_cpu_power3,
111#ifdef CONFIG_OPROFILE
112 .oprofile_cpu_type = "ppc64/rs64", 107 .oprofile_cpu_type = "ppc64/rs64",
113 .oprofile_model = &op_model_rs64, 108 .oprofile_type = RS64,
114#endif
115 }, 109 },
116 { /* Pulsar */ 110 { /* Pulsar */
117 .pvr_mask = 0xffff0000, 111 .pvr_mask = 0xffff0000,
@@ -123,10 +117,8 @@ struct cpu_spec cpu_specs[] = {
123 .dcache_bsize = 128, 117 .dcache_bsize = 128,
124 .num_pmcs = 8, 118 .num_pmcs = 8,
125 .cpu_setup = __setup_cpu_power3, 119 .cpu_setup = __setup_cpu_power3,
126#ifdef CONFIG_OPROFILE
127 .oprofile_cpu_type = "ppc64/rs64", 120 .oprofile_cpu_type = "ppc64/rs64",
128 .oprofile_model = &op_model_rs64, 121 .oprofile_type = RS64,
129#endif
130 }, 122 },
131 { /* I-star */ 123 { /* I-star */
132 .pvr_mask = 0xffff0000, 124 .pvr_mask = 0xffff0000,
@@ -138,10 +130,8 @@ struct cpu_spec cpu_specs[] = {
138 .dcache_bsize = 128, 130 .dcache_bsize = 128,
139 .num_pmcs = 8, 131 .num_pmcs = 8,
140 .cpu_setup = __setup_cpu_power3, 132 .cpu_setup = __setup_cpu_power3,
141#ifdef CONFIG_OPROFILE
142 .oprofile_cpu_type = "ppc64/rs64", 133 .oprofile_cpu_type = "ppc64/rs64",
143 .oprofile_model = &op_model_rs64, 134 .oprofile_type = RS64,
144#endif
145 }, 135 },
146 { /* S-star */ 136 { /* S-star */
147 .pvr_mask = 0xffff0000, 137 .pvr_mask = 0xffff0000,
@@ -153,10 +143,8 @@ struct cpu_spec cpu_specs[] = {
153 .dcache_bsize = 128, 143 .dcache_bsize = 128,
154 .num_pmcs = 8, 144 .num_pmcs = 8,
155 .cpu_setup = __setup_cpu_power3, 145 .cpu_setup = __setup_cpu_power3,
156#ifdef CONFIG_OPROFILE
157 .oprofile_cpu_type = "ppc64/rs64", 146 .oprofile_cpu_type = "ppc64/rs64",
158 .oprofile_model = &op_model_rs64, 147 .oprofile_type = RS64,
159#endif
160 }, 148 },
161 { /* Power4 */ 149 { /* Power4 */
162 .pvr_mask = 0xffff0000, 150 .pvr_mask = 0xffff0000,
@@ -168,10 +156,8 @@ struct cpu_spec cpu_specs[] = {
168 .dcache_bsize = 128, 156 .dcache_bsize = 128,
169 .num_pmcs = 8, 157 .num_pmcs = 8,
170 .cpu_setup = __setup_cpu_power4, 158 .cpu_setup = __setup_cpu_power4,
171#ifdef CONFIG_OPROFILE
172 .oprofile_cpu_type = "ppc64/power4", 159 .oprofile_cpu_type = "ppc64/power4",
173 .oprofile_model = &op_model_rs64, 160 .oprofile_type = POWER4,
174#endif
175 }, 161 },
176 { /* Power4+ */ 162 { /* Power4+ */
177 .pvr_mask = 0xffff0000, 163 .pvr_mask = 0xffff0000,
@@ -183,10 +169,8 @@ struct cpu_spec cpu_specs[] = {
183 .dcache_bsize = 128, 169 .dcache_bsize = 128,
184 .num_pmcs = 8, 170 .num_pmcs = 8,
185 .cpu_setup = __setup_cpu_power4, 171 .cpu_setup = __setup_cpu_power4,
186#ifdef CONFIG_OPROFILE
187 .oprofile_cpu_type = "ppc64/power4", 172 .oprofile_cpu_type = "ppc64/power4",
188 .oprofile_model = &op_model_power4, 173 .oprofile_type = POWER4,
189#endif
190 }, 174 },
191 { /* PPC970 */ 175 { /* PPC970 */
192 .pvr_mask = 0xffff0000, 176 .pvr_mask = 0xffff0000,
@@ -199,10 +183,8 @@ struct cpu_spec cpu_specs[] = {
199 .dcache_bsize = 128, 183 .dcache_bsize = 128,
200 .num_pmcs = 8, 184 .num_pmcs = 8,
201 .cpu_setup = __setup_cpu_ppc970, 185 .cpu_setup = __setup_cpu_ppc970,
202#ifdef CONFIG_OPROFILE
203 .oprofile_cpu_type = "ppc64/970", 186 .oprofile_cpu_type = "ppc64/970",
204 .oprofile_model = &op_model_power4, 187 .oprofile_type = POWER4,
205#endif
206 }, 188 },
207#endif /* CONFIG_PPC64 */ 189#endif /* CONFIG_PPC64 */
208#if defined(CONFIG_PPC64) || defined(CONFIG_POWER4) 190#if defined(CONFIG_PPC64) || defined(CONFIG_POWER4)
@@ -221,10 +203,8 @@ struct cpu_spec cpu_specs[] = {
221 .dcache_bsize = 128, 203 .dcache_bsize = 128,
222 .num_pmcs = 8, 204 .num_pmcs = 8,
223 .cpu_setup = __setup_cpu_ppc970, 205 .cpu_setup = __setup_cpu_ppc970,
224#ifdef CONFIG_OPROFILE
225 .oprofile_cpu_type = "ppc64/970", 206 .oprofile_cpu_type = "ppc64/970",
226 .oprofile_model = &op_model_power4, 207 .oprofile_type = POWER4,
227#endif
228 }, 208 },
229#endif /* defined(CONFIG_PPC64) || defined(CONFIG_POWER4) */ 209#endif /* defined(CONFIG_PPC64) || defined(CONFIG_POWER4) */
230#ifdef CONFIG_PPC64 210#ifdef CONFIG_PPC64
@@ -238,10 +218,8 @@ struct cpu_spec cpu_specs[] = {
238 .icache_bsize = 128, 218 .icache_bsize = 128,
239 .dcache_bsize = 128, 219 .dcache_bsize = 128,
240 .cpu_setup = __setup_cpu_ppc970, 220 .cpu_setup = __setup_cpu_ppc970,
241#ifdef CONFIG_OPROFILE
242 .oprofile_cpu_type = "ppc64/970", 221 .oprofile_cpu_type = "ppc64/970",
243 .oprofile_model = &op_model_power4, 222 .oprofile_type = POWER4,
244#endif
245 }, 223 },
246 { /* Power5 GR */ 224 { /* Power5 GR */
247 .pvr_mask = 0xffff0000, 225 .pvr_mask = 0xffff0000,
@@ -253,27 +231,23 @@ struct cpu_spec cpu_specs[] = {
253 .dcache_bsize = 128, 231 .dcache_bsize = 128,
254 .num_pmcs = 6, 232 .num_pmcs = 6,
255 .cpu_setup = __setup_cpu_power4, 233 .cpu_setup = __setup_cpu_power4,
256#ifdef CONFIG_OPROFILE
257 .oprofile_cpu_type = "ppc64/power5", 234 .oprofile_cpu_type = "ppc64/power5",
258 .oprofile_model = &op_model_power4, 235 .oprofile_type = POWER4,
259#endif
260 }, 236 },
261 { /* Power5 GS */ 237 { /* Power5 GS */
262 .pvr_mask = 0xffff0000, 238 .pvr_mask = 0xffff0000,
263 .pvr_value = 0x003b0000, 239 .pvr_value = 0x003b0000,
264 .cpu_name = "POWER5 (gs)", 240 .cpu_name = "POWER5+ (gs)",
265 .cpu_features = CPU_FTRS_POWER5, 241 .cpu_features = CPU_FTRS_POWER5,
266 .cpu_user_features = COMMON_USER_POWER5_PLUS, 242 .cpu_user_features = COMMON_USER_POWER5_PLUS,
267 .icache_bsize = 128, 243 .icache_bsize = 128,
268 .dcache_bsize = 128, 244 .dcache_bsize = 128,
269 .num_pmcs = 6, 245 .num_pmcs = 6,
270 .cpu_setup = __setup_cpu_power4, 246 .cpu_setup = __setup_cpu_power4,
271#ifdef CONFIG_OPROFILE 247 .oprofile_cpu_type = "ppc64/power5+",
272 .oprofile_cpu_type = "ppc64/power5", 248 .oprofile_type = POWER4,
273 .oprofile_model = &op_model_power4,
274#endif
275 }, 249 },
276 { /* BE DD1.x */ 250 { /* Cell Broadband Engine */
277 .pvr_mask = 0xffff0000, 251 .pvr_mask = 0xffff0000,
278 .pvr_value = 0x00700000, 252 .pvr_value = 0x00700000,
279 .cpu_name = "Cell Broadband Engine", 253 .cpu_name = "Cell Broadband Engine",
@@ -545,7 +519,9 @@ struct cpu_spec cpu_specs[] = {
545 .icache_bsize = 32, 519 .icache_bsize = 32,
546 .dcache_bsize = 32, 520 .dcache_bsize = 32,
547 .num_pmcs = 6, 521 .num_pmcs = 6,
548 .cpu_setup = __setup_cpu_745x 522 .cpu_setup = __setup_cpu_745x,
523 .oprofile_cpu_type = "ppc/7450",
524 .oprofile_type = G4,
549 }, 525 },
550 { /* 7450 2.1 */ 526 { /* 7450 2.1 */
551 .pvr_mask = 0xffffffff, 527 .pvr_mask = 0xffffffff,
@@ -556,7 +532,9 @@ struct cpu_spec cpu_specs[] = {
556 .icache_bsize = 32, 532 .icache_bsize = 32,
557 .dcache_bsize = 32, 533 .dcache_bsize = 32,
558 .num_pmcs = 6, 534 .num_pmcs = 6,
559 .cpu_setup = __setup_cpu_745x 535 .cpu_setup = __setup_cpu_745x,
536 .oprofile_cpu_type = "ppc/7450",
537 .oprofile_type = G4,
560 }, 538 },
561 { /* 7450 2.3 and newer */ 539 { /* 7450 2.3 and newer */
562 .pvr_mask = 0xffff0000, 540 .pvr_mask = 0xffff0000,
@@ -567,7 +545,9 @@ struct cpu_spec cpu_specs[] = {
567 .icache_bsize = 32, 545 .icache_bsize = 32,
568 .dcache_bsize = 32, 546 .dcache_bsize = 32,
569 .num_pmcs = 6, 547 .num_pmcs = 6,
570 .cpu_setup = __setup_cpu_745x 548 .cpu_setup = __setup_cpu_745x,
549 .oprofile_cpu_type = "ppc/7450",
550 .oprofile_type = G4,
571 }, 551 },
572 { /* 7455 rev 1.x */ 552 { /* 7455 rev 1.x */
573 .pvr_mask = 0xffffff00, 553 .pvr_mask = 0xffffff00,
@@ -578,7 +558,9 @@ struct cpu_spec cpu_specs[] = {
578 .icache_bsize = 32, 558 .icache_bsize = 32,
579 .dcache_bsize = 32, 559 .dcache_bsize = 32,
580 .num_pmcs = 6, 560 .num_pmcs = 6,
581 .cpu_setup = __setup_cpu_745x 561 .cpu_setup = __setup_cpu_745x,
562 .oprofile_cpu_type = "ppc/7450",
563 .oprofile_type = G4,
582 }, 564 },
583 { /* 7455 rev 2.0 */ 565 { /* 7455 rev 2.0 */
584 .pvr_mask = 0xffffffff, 566 .pvr_mask = 0xffffffff,
@@ -589,7 +571,9 @@ struct cpu_spec cpu_specs[] = {
589 .icache_bsize = 32, 571 .icache_bsize = 32,
590 .dcache_bsize = 32, 572 .dcache_bsize = 32,
591 .num_pmcs = 6, 573 .num_pmcs = 6,
592 .cpu_setup = __setup_cpu_745x 574 .cpu_setup = __setup_cpu_745x,
575 .oprofile_cpu_type = "ppc/7450",
576 .oprofile_type = G4,
593 }, 577 },
594 { /* 7455 others */ 578 { /* 7455 others */
595 .pvr_mask = 0xffff0000, 579 .pvr_mask = 0xffff0000,
@@ -600,7 +584,9 @@ struct cpu_spec cpu_specs[] = {
600 .icache_bsize = 32, 584 .icache_bsize = 32,
601 .dcache_bsize = 32, 585 .dcache_bsize = 32,
602 .num_pmcs = 6, 586 .num_pmcs = 6,
603 .cpu_setup = __setup_cpu_745x 587 .cpu_setup = __setup_cpu_745x,
588 .oprofile_cpu_type = "ppc/7450",
589 .oprofile_type = G4,
604 }, 590 },
605 { /* 7447/7457 Rev 1.0 */ 591 { /* 7447/7457 Rev 1.0 */
606 .pvr_mask = 0xffffffff, 592 .pvr_mask = 0xffffffff,
@@ -611,7 +597,9 @@ struct cpu_spec cpu_specs[] = {
611 .icache_bsize = 32, 597 .icache_bsize = 32,
612 .dcache_bsize = 32, 598 .dcache_bsize = 32,
613 .num_pmcs = 6, 599 .num_pmcs = 6,
614 .cpu_setup = __setup_cpu_745x 600 .cpu_setup = __setup_cpu_745x,
601 .oprofile_cpu_type = "ppc/7450",
602 .oprofile_type = G4,
615 }, 603 },
616 { /* 7447/7457 Rev 1.1 */ 604 { /* 7447/7457 Rev 1.1 */
617 .pvr_mask = 0xffffffff, 605 .pvr_mask = 0xffffffff,
@@ -622,7 +610,9 @@ struct cpu_spec cpu_specs[] = {
622 .icache_bsize = 32, 610 .icache_bsize = 32,
623 .dcache_bsize = 32, 611 .dcache_bsize = 32,
624 .num_pmcs = 6, 612 .num_pmcs = 6,
625 .cpu_setup = __setup_cpu_745x 613 .cpu_setup = __setup_cpu_745x,
614 .oprofile_cpu_type = "ppc/7450",
615 .oprofile_type = G4,
626 }, 616 },
627 { /* 7447/7457 Rev 1.2 and later */ 617 { /* 7447/7457 Rev 1.2 and later */
628 .pvr_mask = 0xffff0000, 618 .pvr_mask = 0xffff0000,
@@ -633,7 +623,9 @@ struct cpu_spec cpu_specs[] = {
633 .icache_bsize = 32, 623 .icache_bsize = 32,
634 .dcache_bsize = 32, 624 .dcache_bsize = 32,
635 .num_pmcs = 6, 625 .num_pmcs = 6,
636 .cpu_setup = __setup_cpu_745x 626 .cpu_setup = __setup_cpu_745x,
627 .oprofile_cpu_type = "ppc/7450",
628 .oprofile_type = G4,
637 }, 629 },
638 { /* 7447A */ 630 { /* 7447A */
639 .pvr_mask = 0xffff0000, 631 .pvr_mask = 0xffff0000,
@@ -644,7 +636,9 @@ struct cpu_spec cpu_specs[] = {
644 .icache_bsize = 32, 636 .icache_bsize = 32,
645 .dcache_bsize = 32, 637 .dcache_bsize = 32,
646 .num_pmcs = 6, 638 .num_pmcs = 6,
647 .cpu_setup = __setup_cpu_745x 639 .cpu_setup = __setup_cpu_745x,
640 .oprofile_cpu_type = "ppc/7450",
641 .oprofile_type = G4,
648 }, 642 },
649 { /* 7448 */ 643 { /* 7448 */
650 .pvr_mask = 0xffff0000, 644 .pvr_mask = 0xffff0000,
@@ -655,7 +649,9 @@ struct cpu_spec cpu_specs[] = {
655 .icache_bsize = 32, 649 .icache_bsize = 32,
656 .dcache_bsize = 32, 650 .dcache_bsize = 32,
657 .num_pmcs = 6, 651 .num_pmcs = 6,
658 .cpu_setup = __setup_cpu_745x 652 .cpu_setup = __setup_cpu_745x,
653 .oprofile_cpu_type = "ppc/7450",
654 .oprofile_type = G4,
659 }, 655 },
660 { /* 82xx (8240, 8245, 8260 are all 603e cores) */ 656 { /* 82xx (8240, 8245, 8260 are all 603e cores) */
661 .pvr_mask = 0x7fff0000, 657 .pvr_mask = 0x7fff0000,
@@ -979,6 +975,8 @@ struct cpu_spec cpu_specs[] = {
979 .icache_bsize = 32, 975 .icache_bsize = 32,
980 .dcache_bsize = 32, 976 .dcache_bsize = 32,
981 .num_pmcs = 4, 977 .num_pmcs = 4,
978 .oprofile_cpu_type = "ppc/e500",
979 .oprofile_type = BOOKE,
982 }, 980 },
983 { /* e500v2 */ 981 { /* e500v2 */
984 .pvr_mask = 0xffff0000, 982 .pvr_mask = 0xffff0000,
@@ -992,6 +990,8 @@ struct cpu_spec cpu_specs[] = {
992 .icache_bsize = 32, 990 .icache_bsize = 32,
993 .dcache_bsize = 32, 991 .dcache_bsize = 32,
994 .num_pmcs = 4, 992 .num_pmcs = 4,
993 .oprofile_cpu_type = "ppc/e500",
994 .oprofile_type = BOOKE,
995 }, 995 },
996#endif 996#endif
997#if !CLASSIC_PPC 997#if !CLASSIC_PPC
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
new file mode 100644
index 000000000000..4681155121ef
--- /dev/null
+++ b/arch/powerpc/kernel/crash.c
@@ -0,0 +1,264 @@
1/*
2 * Architecture specific (PPC64) functions for kexec based crash dumps.
3 *
4 * Copyright (C) 2005, IBM Corp.
5 *
6 * Created by: Haren Myneni
7 *
8 * This source code is licensed under the GNU General Public License,
9 * Version 2. See the file COPYING for more details.
10 *
11 */
12
13#undef DEBUG
14
15#include <linux/kernel.h>
16#include <linux/smp.h>
17#include <linux/reboot.h>
18#include <linux/kexec.h>
19#include <linux/bootmem.h>
20#include <linux/crash_dump.h>
21#include <linux/irq.h>
22#include <linux/delay.h>
23#include <linux/elf.h>
24#include <linux/elfcore.h>
25#include <linux/init.h>
26#include <linux/types.h>
27
28#include <asm/processor.h>
29#include <asm/machdep.h>
30#include <asm/kdump.h>
31#include <asm/lmb.h>
32#include <asm/firmware.h>
33
34#ifdef DEBUG
35#include <asm/udbg.h>
36#define DBG(fmt...) udbg_printf(fmt)
37#else
38#define DBG(fmt...)
39#endif
40
41/* This keeps a track of which one is crashing cpu. */
42int crashing_cpu = -1;
43
44static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
45 size_t data_len)
46{
47 struct elf_note note;
48
49 note.n_namesz = strlen(name) + 1;
50 note.n_descsz = data_len;
51 note.n_type = type;
52 memcpy(buf, &note, sizeof(note));
53 buf += (sizeof(note) +3)/4;
54 memcpy(buf, name, note.n_namesz);
55 buf += (note.n_namesz + 3)/4;
56 memcpy(buf, data, note.n_descsz);
57 buf += (note.n_descsz + 3)/4;
58
59 return buf;
60}
61
62static void final_note(u32 *buf)
63{
64 struct elf_note note;
65
66 note.n_namesz = 0;
67 note.n_descsz = 0;
68 note.n_type = 0;
69 memcpy(buf, &note, sizeof(note));
70}
71
72static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
73{
74 struct elf_prstatus prstatus;
75 u32 *buf;
76
77 if ((cpu < 0) || (cpu >= NR_CPUS))
78 return;
79
80 /* Using ELF notes here is opportunistic.
81 * I need a well defined structure format
82 * for the data I pass, and I need tags
83 * on the data to indicate what information I have
84 * squirrelled away. ELF notes happen to provide
85 * all of that that no need to invent something new.
86 */
87 buf = &crash_notes[cpu][0];
88 memset(&prstatus, 0, sizeof(prstatus));
89 prstatus.pr_pid = current->pid;
90 elf_core_copy_regs(&prstatus.pr_reg, regs);
91 buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
92 sizeof(prstatus));
93 final_note(buf);
94}
95
96/* FIXME Merge this with xmon_save_regs ?? */
97static inline void crash_get_current_regs(struct pt_regs *regs)
98{
99 unsigned long tmp1, tmp2;
100
101 __asm__ __volatile__ (
102 "std 0,0(%2)\n"
103 "std 1,8(%2)\n"
104 "std 2,16(%2)\n"
105 "std 3,24(%2)\n"
106 "std 4,32(%2)\n"
107 "std 5,40(%2)\n"
108 "std 6,48(%2)\n"
109 "std 7,56(%2)\n"
110 "std 8,64(%2)\n"
111 "std 9,72(%2)\n"
112 "std 10,80(%2)\n"
113 "std 11,88(%2)\n"
114 "std 12,96(%2)\n"
115 "std 13,104(%2)\n"
116 "std 14,112(%2)\n"
117 "std 15,120(%2)\n"
118 "std 16,128(%2)\n"
119 "std 17,136(%2)\n"
120 "std 18,144(%2)\n"
121 "std 19,152(%2)\n"
122 "std 20,160(%2)\n"
123 "std 21,168(%2)\n"
124 "std 22,176(%2)\n"
125 "std 23,184(%2)\n"
126 "std 24,192(%2)\n"
127 "std 25,200(%2)\n"
128 "std 26,208(%2)\n"
129 "std 27,216(%2)\n"
130 "std 28,224(%2)\n"
131 "std 29,232(%2)\n"
132 "std 30,240(%2)\n"
133 "std 31,248(%2)\n"
134 "mfmsr %0\n"
135 "std %0, 264(%2)\n"
136 "mfctr %0\n"
137 "std %0, 280(%2)\n"
138 "mflr %0\n"
139 "std %0, 288(%2)\n"
140 "bl 1f\n"
141 "1: mflr %1\n"
142 "std %1, 256(%2)\n"
143 "mtlr %0\n"
144 "mfxer %0\n"
145 "std %0, 296(%2)\n"
146 : "=&r" (tmp1), "=&r" (tmp2)
147 : "b" (regs));
148}
149
150/* We may have saved_regs from where the error came from
151 * or it is NULL if via a direct panic().
152 */
153static void crash_save_self(struct pt_regs *saved_regs)
154{
155 struct pt_regs regs;
156 int cpu;
157
158 cpu = smp_processor_id();
159 if (saved_regs)
160 memcpy(&regs, saved_regs, sizeof(regs));
161 else
162 crash_get_current_regs(&regs);
163 crash_save_this_cpu(&regs, cpu);
164}
165
166#ifdef CONFIG_SMP
167static atomic_t waiting_for_crash_ipi;
168
169void crash_ipi_callback(struct pt_regs *regs)
170{
171 int cpu = smp_processor_id();
172
173 if (cpu == crashing_cpu)
174 return;
175
176 if (!cpu_online(cpu))
177 return;
178
179 if (ppc_md.kexec_cpu_down)
180 ppc_md.kexec_cpu_down(1, 1);
181
182 local_irq_disable();
183
184 crash_save_this_cpu(regs, cpu);
185 atomic_dec(&waiting_for_crash_ipi);
186 kexec_smp_wait();
187 /* NOTREACHED */
188}
189
190static void crash_kexec_prepare_cpus(void)
191{
192 unsigned int msecs;
193
194 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
195
196 crash_send_ipi(crash_ipi_callback);
197 smp_wmb();
198
199 /*
200 * FIXME: Until we will have the way to stop other CPUSs reliabally,
201 * the crash CPU will send an IPI and wait for other CPUs to
202 * respond. If not, proceed the kexec boot even though we failed to
203 * capture other CPU states.
204 */
205 msecs = 1000000;
206 while ((atomic_read(&waiting_for_crash_ipi) > 0) && (--msecs > 0)) {
207 barrier();
208 mdelay(1);
209 }
210
211 /* Would it be better to replace the trap vector here? */
212
213 /*
214 * FIXME: In case if we do not get all CPUs, one possibility: ask the
215 * user to do soft reset such that we get all.
216 * IPI handler is already set by the panic cpu initially. Therefore,
217 * all cpus could invoke this handler from die() and the panic CPU
218 * will call machine_kexec() directly from this handler to do
219 * kexec boot.
220 */
221 if (atomic_read(&waiting_for_crash_ipi))
222 printk(KERN_ALERT "done waiting: %d cpus not responding\n",
223 atomic_read(&waiting_for_crash_ipi));
224 /* Leave the IPI callback set */
225}
226#else
227static void crash_kexec_prepare_cpus(void)
228{
229 /*
230 * move the secondarys to us so that we can copy
231 * the new kernel 0-0x100 safely
232 *
233 * do this if kexec in setup.c ?
234 */
235 smp_release_cpus();
236}
237
238#endif
239
240void default_machine_crash_shutdown(struct pt_regs *regs)
241{
242 /*
243 * This function is only called after the system
244 * has paniced or is otherwise in a critical state.
245 * The minimum amount of code to allow a kexec'd kernel
246 * to run successfully needs to happen here.
247 *
248 * In practice this means stopping other cpus in
249 * an SMP system.
250 * The kernel is broken so disable interrupts.
251 */
252 local_irq_disable();
253
254 if (ppc_md.kexec_cpu_down)
255 ppc_md.kexec_cpu_down(1, 0);
256
257 /*
258 * Make a note of crashing cpu. Will be used in machine_kexec
259 * such that another IPI will not be sent.
260 */
261 crashing_cpu = smp_processor_id();
262 crash_kexec_prepare_cpus();
263 crash_save_self(regs);
264}
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
new file mode 100644
index 000000000000..87effa3f21a7
--- /dev/null
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -0,0 +1,109 @@
1/*
2 * Routines for doing kexec-based kdump.
3 *
4 * Copyright (C) 2005, IBM Corp.
5 *
6 * Created by: Michael Ellerman
7 *
8 * This source code is licensed under the GNU General Public License,
9 * Version 2. See the file COPYING for more details.
10 */
11
12#undef DEBUG
13
14#include <linux/crash_dump.h>
15#include <linux/bootmem.h>
16#include <asm/kdump.h>
17#include <asm/lmb.h>
18#include <asm/firmware.h>
19#include <asm/uaccess.h>
20
21#ifdef DEBUG
22#include <asm/udbg.h>
23#define DBG(fmt...) udbg_printf(fmt)
24#else
25#define DBG(fmt...)
26#endif
27
28static void __init create_trampoline(unsigned long addr)
29{
30 /* The maximum range of a single instruction branch, is the current
31 * instruction's address + (32 MB - 4) bytes. For the trampoline we
32 * need to branch to current address + 32 MB. So we insert a nop at
33 * the trampoline address, then the next instruction (+ 4 bytes)
34 * does a branch to (32 MB - 4). The net effect is that when we
35 * branch to "addr" we jump to ("addr" + 32 MB). Although it requires
36 * two instructions it doesn't require any registers.
37 */
38 create_instruction(addr, 0x60000000); /* nop */
39 create_branch(addr + 4, addr + PHYSICAL_START, 0);
40}
41
42void __init kdump_setup(void)
43{
44 unsigned long i;
45
46 DBG(" -> kdump_setup()\n");
47
48 for (i = KDUMP_TRAMPOLINE_START; i < KDUMP_TRAMPOLINE_END; i += 8) {
49 create_trampoline(i);
50 }
51
52 create_trampoline(__pa(system_reset_fwnmi) - PHYSICAL_START);
53 create_trampoline(__pa(machine_check_fwnmi) - PHYSICAL_START);
54
55 DBG(" <- kdump_setup()\n");
56}
57
58static int __init parse_elfcorehdr(char *p)
59{
60 if (p)
61 elfcorehdr_addr = memparse(p, &p);
62
63 return 0;
64}
65__setup("elfcorehdr=", parse_elfcorehdr);
66
67static int __init parse_savemaxmem(char *p)
68{
69 if (p)
70 saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1;
71
72 return 0;
73}
74__setup("savemaxmem=", parse_savemaxmem);
75
76/*
77 * copy_oldmem_page - copy one page from "oldmem"
78 * @pfn: page frame number to be copied
79 * @buf: target memory address for the copy; this can be in kernel address
80 * space or user address space (see @userbuf)
81 * @csize: number of bytes to copy
82 * @offset: offset in bytes into the page (based on pfn) to begin the copy
83 * @userbuf: if set, @buf is in user address space, use copy_to_user(),
84 * otherwise @buf is in kernel address space, use memcpy().
85 *
86 * Copy a page from "oldmem". For this page, there is no pte mapped
87 * in the current kernel. We stitch up a pte, similar to kmap_atomic.
88 */
89ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
90 size_t csize, unsigned long offset, int userbuf)
91{
92 void *vaddr;
93
94 if (!csize)
95 return 0;
96
97 vaddr = __ioremap(pfn << PAGE_SHIFT, PAGE_SIZE, 0);
98
99 if (userbuf) {
100 if (copy_to_user((char __user *)buf, (vaddr + offset), csize)) {
101 iounmap(vaddr);
102 return -EFAULT;
103 }
104 } else
105 memcpy(buf, (vaddr + offset), csize);
106
107 iounmap(vaddr);
108 return csize;
109}
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 7c3419656ccc..36aaa7663f02 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -10,6 +10,7 @@
10/* Include the busses we support */ 10/* Include the busses we support */
11#include <linux/pci.h> 11#include <linux/pci.h>
12#include <asm/vio.h> 12#include <asm/vio.h>
13#include <asm/ibmebus.h>
13#include <asm/scatterlist.h> 14#include <asm/scatterlist.h>
14#include <asm/bug.h> 15#include <asm/bug.h>
15 16
@@ -23,6 +24,10 @@ static struct dma_mapping_ops *get_dma_ops(struct device *dev)
23 if (dev->bus == &vio_bus_type) 24 if (dev->bus == &vio_bus_type)
24 return &vio_dma_ops; 25 return &vio_dma_ops;
25#endif 26#endif
27#ifdef CONFIG_IBMEBUS
28 if (dev->bus == &ibmebus_bus_type)
29 return &ibmebus_dma_ops;
30#endif
26 return NULL; 31 return NULL;
27} 32}
28 33
@@ -47,6 +52,10 @@ int dma_set_mask(struct device *dev, u64 dma_mask)
47 if (dev->bus == &vio_bus_type) 52 if (dev->bus == &vio_bus_type)
48 return -EIO; 53 return -EIO;
49#endif /* CONFIG_IBMVIO */ 54#endif /* CONFIG_IBMVIO */
55#ifdef CONFIG_IBMEBUS
56 if (dev->bus == &ibmebus_bus_type)
57 return -EIO;
58#endif
50 BUG(); 59 BUG();
51 return 0; 60 return 0;
52} 61}
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 2e99ae41723c..036b71d2adfc 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -200,8 +200,6 @@ _GLOBAL(DoSyscall)
200 bl do_show_syscall 200 bl do_show_syscall
201#endif /* SHOW_SYSCALLS */ 201#endif /* SHOW_SYSCALLS */
202 rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ 202 rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
203 li r11,0
204 stb r11,TI_SC_NOERR(r10)
205 lwz r11,TI_FLAGS(r10) 203 lwz r11,TI_FLAGS(r10)
206 andi. r11,r11,_TIF_SYSCALL_T_OR_A 204 andi. r11,r11,_TIF_SYSCALL_T_OR_A
207 bne- syscall_dotrace 205 bne- syscall_dotrace
@@ -222,25 +220,21 @@ ret_from_syscall:
222 bl do_show_syscall_exit 220 bl do_show_syscall_exit
223#endif 221#endif
224 mr r6,r3 222 mr r6,r3
225 li r11,-_LAST_ERRNO
226 cmplw 0,r3,r11
227 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ 223 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
228 blt+ 30f
229 lbz r11,TI_SC_NOERR(r12)
230 cmpwi r11,0
231 bne 30f
232 neg r3,r3
233 lwz r10,_CCR(r1) /* Set SO bit in CR */
234 oris r10,r10,0x1000
235 stw r10,_CCR(r1)
236
237 /* disable interrupts so current_thread_info()->flags can't change */ 224 /* disable interrupts so current_thread_info()->flags can't change */
23830: LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ 225 LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
239 SYNC 226 SYNC
240 MTMSRD(r10) 227 MTMSRD(r10)
241 lwz r9,TI_FLAGS(r12) 228 lwz r9,TI_FLAGS(r12)
242 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED) 229 li r8,-_LAST_ERRNO
230 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
243 bne- syscall_exit_work 231 bne- syscall_exit_work
232 cmplw 0,r3,r8
233 blt+ syscall_exit_cont
234 lwz r11,_CCR(r1) /* Load CR */
235 neg r3,r3
236 oris r11,r11,0x1000 /* Set SO bit in CR */
237 stw r11,_CCR(r1)
244syscall_exit_cont: 238syscall_exit_cont:
245#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) 239#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
246 /* If the process has its own DBCR0 value, load it up. The single 240 /* If the process has its own DBCR0 value, load it up. The single
@@ -292,46 +286,113 @@ syscall_dotrace:
292 b syscall_dotrace_cont 286 b syscall_dotrace_cont
293 287
294syscall_exit_work: 288syscall_exit_work:
295 stw r6,RESULT(r1) /* Save result */ 289 andi. r0,r9,_TIF_RESTOREALL
290 bne- 2f
291 cmplw 0,r3,r8
292 blt+ 1f
293 andi. r0,r9,_TIF_NOERROR
294 bne- 1f
295 lwz r11,_CCR(r1) /* Load CR */
296 neg r3,r3
297 oris r11,r11,0x1000 /* Set SO bit in CR */
298 stw r11,_CCR(r1)
299
3001: stw r6,RESULT(r1) /* Save result */
296 stw r3,GPR3(r1) /* Update return value */ 301 stw r3,GPR3(r1) /* Update return value */
297 andi. r0,r9,_TIF_SYSCALL_T_OR_A 3022: andi. r0,r9,(_TIF_PERSYSCALL_MASK)
298 beq 5f 303 beq 4f
299 ori r10,r10,MSR_EE 304
300 SYNC 305 /* Clear per-syscall TIF flags if any are set, but _leave_
301 MTMSRD(r10) /* re-enable interrupts */ 306 _TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that
307 yet. */
308
309 li r11,_TIF_PERSYSCALL_MASK
310 addi r12,r12,TI_FLAGS
3113: lwarx r8,0,r12
312 andc r8,r8,r11
313#ifdef CONFIG_IBM405_ERR77
314 dcbt 0,r12
315#endif
316 stwcx. r8,0,r12
317 bne- 3b
318 subi r12,r12,TI_FLAGS
319
3204: /* Anything which requires enabling interrupts? */
321 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS)
322 beq 7f
323
324 /* Save NVGPRS if they're not saved already */
302 lwz r4,_TRAP(r1) 325 lwz r4,_TRAP(r1)
303 andi. r4,r4,1 326 andi. r4,r4,1
304 beq 4f 327 beq 5f
305 SAVE_NVGPRS(r1) 328 SAVE_NVGPRS(r1)
306 li r4,0xc00 329 li r4,0xc00
307 stw r4,_TRAP(r1) 330 stw r4,_TRAP(r1)
3084: 331
332 /* Re-enable interrupts */
3335: ori r10,r10,MSR_EE
334 SYNC
335 MTMSRD(r10)
336
337 andi. r0,r9,_TIF_SAVE_NVGPRS
338 bne save_user_nvgprs
339
340save_user_nvgprs_cont:
341 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
342 beq 7f
343
309 addi r3,r1,STACK_FRAME_OVERHEAD 344 addi r3,r1,STACK_FRAME_OVERHEAD
310 bl do_syscall_trace_leave 345 bl do_syscall_trace_leave
311 REST_NVGPRS(r1) 346 REST_NVGPRS(r1)
3122: 347
313 lwz r3,GPR3(r1) 3486: lwz r3,GPR3(r1)
314 LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ 349 LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
315 SYNC 350 SYNC
316 MTMSRD(r10) /* disable interrupts again */ 351 MTMSRD(r10) /* disable interrupts again */
317 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ 352 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
318 lwz r9,TI_FLAGS(r12) 353 lwz r9,TI_FLAGS(r12)
3195: 3547:
320 andi. r0,r9,_TIF_NEED_RESCHED 355 andi. r0,r9,_TIF_NEED_RESCHED
321 bne 1f 356 bne 8f
322 lwz r5,_MSR(r1) 357 lwz r5,_MSR(r1)
323 andi. r5,r5,MSR_PR 358 andi. r5,r5,MSR_PR
324 beq syscall_exit_cont 359 beq ret_from_except
325 andi. r0,r9,_TIF_SIGPENDING 360 andi. r0,r9,_TIF_SIGPENDING
326 beq syscall_exit_cont 361 beq ret_from_except
327 b do_user_signal 362 b do_user_signal
3281: 3638:
329 ori r10,r10,MSR_EE 364 ori r10,r10,MSR_EE
330 SYNC 365 SYNC
331 MTMSRD(r10) /* re-enable interrupts */ 366 MTMSRD(r10) /* re-enable interrupts */
332 bl schedule 367 bl schedule
333 b 2b 368 b 6b
369
370save_user_nvgprs:
371 lwz r8,TI_SIGFRAME(r12)
372
373.macro savewords start, end
374 1: stw \start,4*(\start)(r8)
375 .section __ex_table,"a"
376 .align 2
377 .long 1b,save_user_nvgprs_fault
378 .previous
379 .if \end - \start
380 savewords "(\start+1)",\end
381 .endif
382.endm
383 savewords 14,31
384 b save_user_nvgprs_cont
385
386
387save_user_nvgprs_fault:
388 li r3,11 /* SIGSEGV */
389 lwz r4,TI_TASK(r12)
390 bl force_sigsegv
334 391
392 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
393 lwz r9,TI_FLAGS(r12)
394 b save_user_nvgprs_cont
395
335#ifdef SHOW_SYSCALLS 396#ifdef SHOW_SYSCALLS
336do_show_syscall: 397do_show_syscall:
337#ifdef SHOW_SYSCALLS_TASK 398#ifdef SHOW_SYSCALLS_TASK
@@ -401,28 +462,10 @@ show_syscalls_task:
401#endif /* SHOW_SYSCALLS */ 462#endif /* SHOW_SYSCALLS */
402 463
403/* 464/*
404 * The sigsuspend and rt_sigsuspend system calls can call do_signal 465 * The fork/clone functions need to copy the full register set into
405 * and thus put the process into the stopped state where we might 466 * the child process. Therefore we need to save all the nonvolatile
406 * want to examine its user state with ptrace. Therefore we need 467 * registers (r13 - r31) before calling the C code.
407 * to save all the nonvolatile registers (r13 - r31) before calling
408 * the C code.
409 */ 468 */
410 .globl ppc_sigsuspend
411ppc_sigsuspend:
412 SAVE_NVGPRS(r1)
413 lwz r0,_TRAP(r1)
414 rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
415 stw r0,_TRAP(r1) /* register set saved */
416 b sys_sigsuspend
417
418 .globl ppc_rt_sigsuspend
419ppc_rt_sigsuspend:
420 SAVE_NVGPRS(r1)
421 lwz r0,_TRAP(r1)
422 rlwinm r0,r0,0,0,30
423 stw r0,_TRAP(r1)
424 b sys_rt_sigsuspend
425
426 .globl ppc_fork 469 .globl ppc_fork
427ppc_fork: 470ppc_fork:
428 SAVE_NVGPRS(r1) 471 SAVE_NVGPRS(r1)
@@ -447,14 +490,6 @@ ppc_clone:
447 stw r0,_TRAP(r1) /* register set saved */ 490 stw r0,_TRAP(r1) /* register set saved */
448 b sys_clone 491 b sys_clone
449 492
450 .globl ppc_swapcontext
451ppc_swapcontext:
452 SAVE_NVGPRS(r1)
453 lwz r0,_TRAP(r1)
454 rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
455 stw r0,_TRAP(r1) /* register set saved */
456 b sys_swapcontext
457
458/* 493/*
459 * Top-level page fault handling. 494 * Top-level page fault handling.
460 * This is in assembler because if do_page_fault tells us that 495 * This is in assembler because if do_page_fault tells us that
@@ -626,16 +661,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_601)
626 .long ret_from_except 661 .long ret_from_except
627#endif 662#endif
628 663
629 .globl sigreturn_exit
630sigreturn_exit:
631 subi r1,r3,STACK_FRAME_OVERHEAD
632 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
633 lwz r9,TI_FLAGS(r12)
634 andi. r0,r9,_TIF_SYSCALL_T_OR_A
635 beq+ ret_from_except_full
636 bl do_syscall_trace_leave
637 /* fall through */
638
639 .globl ret_from_except_full 664 .globl ret_from_except_full
640ret_from_except_full: 665ret_from_except_full:
641 REST_NVGPRS(r1) 666 REST_NVGPRS(r1)
@@ -658,7 +683,7 @@ user_exc_return: /* r10 contains MSR_KERNEL here */
658 /* Check current_thread_info()->flags */ 683 /* Check current_thread_info()->flags */
659 rlwinm r9,r1,0,0,(31-THREAD_SHIFT) 684 rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
660 lwz r9,TI_FLAGS(r9) 685 lwz r9,TI_FLAGS(r9)
661 andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED) 686 andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
662 bne do_work 687 bne do_work
663 688
664restore_user: 689restore_user:
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index bce33a38399f..aacebb33e98a 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -113,9 +113,7 @@ system_call_common:
113 addi r9,r1,STACK_FRAME_OVERHEAD 113 addi r9,r1,STACK_FRAME_OVERHEAD
114#endif 114#endif
115 clrrdi r11,r1,THREAD_SHIFT 115 clrrdi r11,r1,THREAD_SHIFT
116 li r12,0
117 ld r10,TI_FLAGS(r11) 116 ld r10,TI_FLAGS(r11)
118 stb r12,TI_SC_NOERR(r11)
119 andi. r11,r10,_TIF_SYSCALL_T_OR_A 117 andi. r11,r10,_TIF_SYSCALL_T_OR_A
120 bne- syscall_dotrace 118 bne- syscall_dotrace
121syscall_dotrace_cont: 119syscall_dotrace_cont:
@@ -144,24 +142,12 @@ system_call: /* label this so stack traces look sane */
144 bctrl /* Call handler */ 142 bctrl /* Call handler */
145 143
146syscall_exit: 144syscall_exit:
145 std r3,RESULT(r1)
147#ifdef SHOW_SYSCALLS 146#ifdef SHOW_SYSCALLS
148 std r3,GPR3(r1)
149 bl .do_show_syscall_exit 147 bl .do_show_syscall_exit
150 ld r3,GPR3(r1) 148 ld r3,RESULT(r1)
151#endif 149#endif
152 std r3,RESULT(r1)
153 ld r5,_CCR(r1)
154 li r10,-_LAST_ERRNO
155 cmpld r3,r10
156 clrrdi r12,r1,THREAD_SHIFT 150 clrrdi r12,r1,THREAD_SHIFT
157 bge- syscall_error
158syscall_error_cont:
159
160 /* check for syscall tracing or audit */
161 ld r9,TI_FLAGS(r12)
162 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
163 bne- syscall_exit_trace
164syscall_exit_trace_cont:
165 151
166 /* disable interrupts so current_thread_info()->flags can't change, 152 /* disable interrupts so current_thread_info()->flags can't change,
167 and so that we don't get interrupted after loading SRR0/1. */ 153 and so that we don't get interrupted after loading SRR0/1. */
@@ -173,8 +159,13 @@ syscall_exit_trace_cont:
173 rotldi r10,r10,16 159 rotldi r10,r10,16
174 mtmsrd r10,1 160 mtmsrd r10,1
175 ld r9,TI_FLAGS(r12) 161 ld r9,TI_FLAGS(r12)
176 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED) 162 li r11,-_LAST_ERRNO
163 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR)
177 bne- syscall_exit_work 164 bne- syscall_exit_work
165 cmpld r3,r11
166 ld r5,_CCR(r1)
167 bge- syscall_error
168syscall_error_cont:
178 ld r7,_NIP(r1) 169 ld r7,_NIP(r1)
179 stdcx. r0,0,r1 /* to clear the reservation */ 170 stdcx. r0,0,r1 /* to clear the reservation */
180 andi. r6,r8,MSR_PR 171 andi. r6,r8,MSR_PR
@@ -193,21 +184,12 @@ syscall_exit_trace_cont:
193 rfid 184 rfid
194 b . /* prevent speculative execution */ 185 b . /* prevent speculative execution */
195 186
196syscall_enosys: 187syscall_error:
197 li r3,-ENOSYS
198 std r3,RESULT(r1)
199 clrrdi r12,r1,THREAD_SHIFT
200 ld r5,_CCR(r1)
201
202syscall_error:
203 lbz r11,TI_SC_NOERR(r12)
204 cmpwi 0,r11,0
205 bne- syscall_error_cont
206 neg r3,r3
207 oris r5,r5,0x1000 /* Set SO bit in CR */ 188 oris r5,r5,0x1000 /* Set SO bit in CR */
189 neg r3,r3
208 std r5,_CCR(r1) 190 std r5,_CCR(r1)
209 b syscall_error_cont 191 b syscall_error_cont
210 192
211/* Traced system call support */ 193/* Traced system call support */
212syscall_dotrace: 194syscall_dotrace:
213 bl .save_nvgprs 195 bl .save_nvgprs
@@ -225,21 +207,69 @@ syscall_dotrace:
225 ld r10,TI_FLAGS(r10) 207 ld r10,TI_FLAGS(r10)
226 b syscall_dotrace_cont 208 b syscall_dotrace_cont
227 209
228syscall_exit_trace: 210syscall_enosys:
229 std r3,GPR3(r1) 211 li r3,-ENOSYS
230 bl .save_nvgprs 212 b syscall_exit
213
214syscall_exit_work:
215 /* If TIF_RESTOREALL is set, don't scribble on either r3 or ccr.
216 If TIF_NOERROR is set, just save r3 as it is. */
217
218 andi. r0,r9,_TIF_RESTOREALL
219 bne- 2f
220 cmpld r3,r11 /* r10 is -LAST_ERRNO */
221 blt+ 1f
222 andi. r0,r9,_TIF_NOERROR
223 bne- 1f
224 ld r5,_CCR(r1)
225 neg r3,r3
226 oris r5,r5,0x1000 /* Set SO bit in CR */
227 std r5,_CCR(r1)
2281: std r3,GPR3(r1)
2292: andi. r0,r9,(_TIF_PERSYSCALL_MASK)
230 beq 4f
231
232 /* Clear per-syscall TIF flags if any are set, but _leave_
233 _TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that
234 yet. */
235
236 li r11,_TIF_PERSYSCALL_MASK
237 addi r12,r12,TI_FLAGS
2383: ldarx r10,0,r12
239 andc r10,r10,r11
240 stdcx. r10,0,r12
241 bne- 3b
242 subi r12,r12,TI_FLAGS
243
2444: bl .save_nvgprs
245 /* Anything else left to do? */
246 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS)
247 beq .ret_from_except_lite
248
249 /* Re-enable interrupts */
250 mfmsr r10
251 ori r10,r10,MSR_EE
252 mtmsrd r10,1
253
254 andi. r0,r9,_TIF_SAVE_NVGPRS
255 bne save_user_nvgprs
256
257 /* If tracing, re-enable interrupts and do it */
258save_user_nvgprs_cont:
259 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
260 beq 5f
261
231 addi r3,r1,STACK_FRAME_OVERHEAD 262 addi r3,r1,STACK_FRAME_OVERHEAD
232 bl .do_syscall_trace_leave 263 bl .do_syscall_trace_leave
233 REST_NVGPRS(r1) 264 REST_NVGPRS(r1)
234 ld r3,GPR3(r1)
235 ld r5,_CCR(r1)
236 clrrdi r12,r1,THREAD_SHIFT 265 clrrdi r12,r1,THREAD_SHIFT
237 b syscall_exit_trace_cont
238 266
239/* Stuff to do on exit from a system call. */ 267 /* Disable interrupts again and handle other work if any */
240syscall_exit_work: 2685: mfmsr r10
241 std r3,GPR3(r1) 269 rldicl r10,r10,48,1
242 std r5,_CCR(r1) 270 rotldi r10,r10,16
271 mtmsrd r10,1
272
243 b .ret_from_except_lite 273 b .ret_from_except_lite
244 274
245/* Save non-volatile GPRs, if not already saved. */ 275/* Save non-volatile GPRs, if not already saved. */
@@ -252,6 +282,52 @@ _GLOBAL(save_nvgprs)
252 std r0,_TRAP(r1) 282 std r0,_TRAP(r1)
253 blr 283 blr
254 284
285
286save_user_nvgprs:
287 ld r10,TI_SIGFRAME(r12)
288 andi. r0,r9,_TIF_32BIT
289 beq- save_user_nvgprs_64
290
291 /* 32-bit save to userspace */
292
293.macro savewords start, end
294 1: stw \start,4*(\start)(r10)
295 .section __ex_table,"a"
296 .align 3
297 .llong 1b,save_user_nvgprs_fault
298 .previous
299 .if \end - \start
300 savewords "(\start+1)",\end
301 .endif
302.endm
303 savewords 14,31
304 b save_user_nvgprs_cont
305
306save_user_nvgprs_64:
307 /* 64-bit save to userspace */
308
309.macro savelongs start, end
310 1: std \start,8*(\start)(r10)
311 .section __ex_table,"a"
312 .align 3
313 .llong 1b,save_user_nvgprs_fault
314 .previous
315 .if \end - \start
316 savelongs "(\start+1)",\end
317 .endif
318.endm
319 savelongs 14,31
320 b save_user_nvgprs_cont
321
322save_user_nvgprs_fault:
323 li r3,11 /* SIGSEGV */
324 ld r4,TI_TASK(r12)
325 bl .force_sigsegv
326
327 clrrdi r12,r1,THREAD_SHIFT
328 ld r9,TI_FLAGS(r12)
329 b save_user_nvgprs_cont
330
255/* 331/*
256 * The sigsuspend and rt_sigsuspend system calls can call do_signal 332 * The sigsuspend and rt_sigsuspend system calls can call do_signal
257 * and thus put the process into the stopped state where we might 333 * and thus put the process into the stopped state where we might
@@ -260,35 +336,6 @@ _GLOBAL(save_nvgprs)
260 * the C code. Similarly, fork, vfork and clone need the full 336 * the C code. Similarly, fork, vfork and clone need the full
261 * register state on the stack so that it can be copied to the child. 337 * register state on the stack so that it can be copied to the child.
262 */ 338 */
263_GLOBAL(ppc32_sigsuspend)
264 bl .save_nvgprs
265 bl .compat_sys_sigsuspend
266 b 70f
267
268_GLOBAL(ppc64_rt_sigsuspend)
269 bl .save_nvgprs
270 bl .sys_rt_sigsuspend
271 b 70f
272
273_GLOBAL(ppc32_rt_sigsuspend)
274 bl .save_nvgprs
275 bl .compat_sys_rt_sigsuspend
27670: cmpdi 0,r3,0
277 /* If it returned an error, we need to return via syscall_exit to set
278 the SO bit in cr0 and potentially stop for ptrace. */
279 bne syscall_exit
280 /* If sigsuspend() returns zero, we are going into a signal handler. We
281 may need to call audit_syscall_exit() to mark the exit from sigsuspend() */
282#ifdef CONFIG_AUDITSYSCALL
283 ld r3,PACACURRENT(r13)
284 ld r4,AUDITCONTEXT(r3)
285 cmpdi 0,r4,0
286 beq .ret_from_except /* No audit_context: Leave immediately. */
287 li r4, 2 /* AUDITSC_FAILURE */
288 li r5,-4 /* It's always -EINTR */
289 bl .audit_syscall_exit
290#endif
291 b .ret_from_except
292 339
293_GLOBAL(ppc_fork) 340_GLOBAL(ppc_fork)
294 bl .save_nvgprs 341 bl .save_nvgprs
@@ -305,37 +352,6 @@ _GLOBAL(ppc_clone)
305 bl .sys_clone 352 bl .sys_clone
306 b syscall_exit 353 b syscall_exit
307 354
308_GLOBAL(ppc32_swapcontext)
309 bl .save_nvgprs
310 bl .compat_sys_swapcontext
311 b 80f
312
313_GLOBAL(ppc64_swapcontext)
314 bl .save_nvgprs
315 bl .sys_swapcontext
316 b 80f
317
318_GLOBAL(ppc32_sigreturn)
319 bl .compat_sys_sigreturn
320 b 80f
321
322_GLOBAL(ppc32_rt_sigreturn)
323 bl .compat_sys_rt_sigreturn
324 b 80f
325
326_GLOBAL(ppc64_rt_sigreturn)
327 bl .sys_rt_sigreturn
328
32980: cmpdi 0,r3,0
330 blt syscall_exit
331 clrrdi r4,r1,THREAD_SHIFT
332 ld r4,TI_FLAGS(r4)
333 andi. r4,r4,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
334 beq+ 81f
335 addi r3,r1,STACK_FRAME_OVERHEAD
336 bl .do_syscall_trace_leave
33781: b .ret_from_except
338
339_GLOBAL(ret_from_fork) 355_GLOBAL(ret_from_fork)
340 bl .schedule_tail 356 bl .schedule_tail
341 REST_NVGPRS(r1) 357 REST_NVGPRS(r1)
@@ -674,7 +690,7 @@ _GLOBAL(enter_rtas)
674 690
675 /* Setup our real return addr */ 691 /* Setup our real return addr */
676 SET_REG_TO_LABEL(r4,.rtas_return_loc) 692 SET_REG_TO_LABEL(r4,.rtas_return_loc)
677 SET_REG_TO_CONST(r9,KERNELBASE) 693 SET_REG_TO_CONST(r9,PAGE_OFFSET)
678 sub r4,r4,r9 694 sub r4,r4,r9
679 mtlr r4 695 mtlr r4
680 696
@@ -702,7 +718,7 @@ _GLOBAL(enter_rtas)
702_STATIC(rtas_return_loc) 718_STATIC(rtas_return_loc)
703 /* relocation is off at this point */ 719 /* relocation is off at this point */
704 mfspr r4,SPRN_SPRG3 /* Get PACA */ 720 mfspr r4,SPRN_SPRG3 /* Get PACA */
705 SET_REG_TO_CONST(r5, KERNELBASE) 721 SET_REG_TO_CONST(r5, PAGE_OFFSET)
706 sub r4,r4,r5 /* RELOC the PACA base pointer */ 722 sub r4,r4,r5 /* RELOC the PACA base pointer */
707 723
708 mfmsr r6 724 mfmsr r6
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index ccdf94731e30..03b25f9359f8 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -120,10 +120,25 @@ __start:
120 * because OF may have I/O devices mapped into that area 120 * because OF may have I/O devices mapped into that area
121 * (particularly on CHRP). 121 * (particularly on CHRP).
122 */ 122 */
123#ifdef CONFIG_PPC_MULTIPLATFORM
123 cmpwi 0,r5,0 124 cmpwi 0,r5,0
124 beq 1f 125 beq 1f
125 bl prom_init 126 bl prom_init
126 trap 127 trap
128#endif
129
130/*
131 * Check for BootX signature when supporting PowerMac and branch to
132 * appropriate trampoline if it's present
133 */
134#ifdef CONFIG_PPC_PMAC
1351: lis r31,0x426f
136 ori r31,r31,0x6f58
137 cmpw 0,r3,r31
138 bne 1f
139 bl bootx_init
140 trap
141#endif /* CONFIG_PPC_PMAC */
127 142
1281: mr r31,r3 /* save parameters */ 1431: mr r31,r3 /* save parameters */
129 mr r30,r4 144 mr r30,r4
@@ -153,6 +168,9 @@ __after_mmu_off:
153 bl flush_tlbs 168 bl flush_tlbs
154 169
155 bl initial_bats 170 bl initial_bats
171#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
172 bl setup_disp_bat
173#endif
156 174
157/* 175/*
158 * Call setup_cpu for CPU 0 and initialize 6xx Idle 176 * Call setup_cpu for CPU 0 and initialize 6xx Idle
@@ -450,16 +468,11 @@ SystemCall:
450 * by executing an altivec instruction. 468 * by executing an altivec instruction.
451 */ 469 */
452 . = 0xf00 470 . = 0xf00
453 b Trap_0f 471 b PerformanceMonitor
454 472
455 . = 0xf20 473 . = 0xf20
456 b AltiVecUnavailable 474 b AltiVecUnavailable
457 475
458Trap_0f:
459 EXCEPTION_PROLOG
460 addi r3,r1,STACK_FRAME_OVERHEAD
461 EXC_XFER_EE(0xf00, unknown_exception)
462
463/* 476/*
464 * Handle TLB miss for instruction on 603/603e. 477 * Handle TLB miss for instruction on 603/603e.
465 * Note: we get an alternate set of r0 - r3 to use automatically. 478 * Note: we get an alternate set of r0 - r3 to use automatically.
@@ -703,6 +716,11 @@ AltiVecUnavailable:
703#endif /* CONFIG_ALTIVEC */ 716#endif /* CONFIG_ALTIVEC */
704 EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception) 717 EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception)
705 718
719PerformanceMonitor:
720 EXCEPTION_PROLOG
721 addi r3,r1,STACK_FRAME_OVERHEAD
722 EXC_XFER_STD(0xf00, performance_monitor_exception)
723
706#ifdef CONFIG_ALTIVEC 724#ifdef CONFIG_ALTIVEC
707/* Note that the AltiVec support is closely modeled after the FP 725/* Note that the AltiVec support is closely modeled after the FP
708 * support. Changes to one are likely to be applicable to the 726 * support. Changes to one are likely to be applicable to the
@@ -1306,6 +1324,32 @@ initial_bats:
1306 blr 1324 blr
1307 1325
1308 1326
1327#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
1328setup_disp_bat:
1329 /*
1330 * setup the display bat prepared for us in prom.c
1331 */
1332 mflr r8
1333 bl reloc_offset
1334 mtlr r8
1335 addis r8,r3,disp_BAT@ha
1336 addi r8,r8,disp_BAT@l
1337 cmpwi cr0,r8,0
1338 beqlr
1339 lwz r11,0(r8)
1340 lwz r8,4(r8)
1341 mfspr r9,SPRN_PVR
1342 rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
1343 cmpwi 0,r9,1
1344 beq 1f
1345 mtspr SPRN_DBAT3L,r8
1346 mtspr SPRN_DBAT3U,r11
1347 blr
13481: mtspr SPRN_IBAT3L,r8
1349 mtspr SPRN_IBAT3U,r11
1350 blr
1351#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */
1352
1309#ifdef CONFIG_8260 1353#ifdef CONFIG_8260
1310/* Jump into the system reset for the rom. 1354/* Jump into the system reset for the rom.
1311 * We first disable the MMU, and then jump to the ROM reset address. 1355 * We first disable the MMU, and then jump to the ROM reset address.
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 8a8bf79ef044..1c066d125375 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -154,11 +154,15 @@ _GLOBAL(__secondary_hold)
154 bne 100b 154 bne 100b
155 155
156#ifdef CONFIG_HMT 156#ifdef CONFIG_HMT
157 b .hmt_init 157 LOADADDR(r4, .hmt_init)
158 mtctr r4
159 bctr
158#else 160#else
159#ifdef CONFIG_SMP 161#ifdef CONFIG_SMP
162 LOADADDR(r4, .pSeries_secondary_smp_init)
163 mtctr r4
160 mr r3,r24 164 mr r3,r24
161 b .pSeries_secondary_smp_init 165 bctr
162#else 166#else
163 BUG_OPCODE 167 BUG_OPCODE
164#endif 168#endif
@@ -200,6 +204,20 @@ exception_marker:
200#define EX_R3 64 204#define EX_R3 64
201#define EX_LR 72 205#define EX_LR 72
202 206
207/*
208 * We're short on space and time in the exception prolog, so we can't use
209 * the normal LOADADDR macro. Normally we just need the low halfword of the
210 * address, but for Kdump we need the whole low word.
211 */
212#ifdef CONFIG_CRASH_DUMP
213#define LOAD_HANDLER(reg, label) \
214 oris reg,reg,(label)@h; /* virt addr of handler ... */ \
215 ori reg,reg,(label)@l; /* .. and the rest */
216#else
217#define LOAD_HANDLER(reg, label) \
218 ori reg,reg,(label)@l; /* virt addr of handler ... */
219#endif
220
203#define EXCEPTION_PROLOG_PSERIES(area, label) \ 221#define EXCEPTION_PROLOG_PSERIES(area, label) \
204 mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ 222 mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
205 std r9,area+EX_R9(r13); /* save r9 - r12 */ \ 223 std r9,area+EX_R9(r13); /* save r9 - r12 */ \
@@ -212,7 +230,7 @@ exception_marker:
212 clrrdi r12,r13,32; /* get high part of &label */ \ 230 clrrdi r12,r13,32; /* get high part of &label */ \
213 mfmsr r10; \ 231 mfmsr r10; \
214 mfspr r11,SPRN_SRR0; /* save SRR0 */ \ 232 mfspr r11,SPRN_SRR0; /* save SRR0 */ \
215 ori r12,r12,(label)@l; /* virt addr of handler */ \ 233 LOAD_HANDLER(r12,label) \
216 ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ 234 ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
217 mtspr SPRN_SRR0,r12; \ 235 mtspr SPRN_SRR0,r12; \
218 mfspr r12,SPRN_SRR1; /* and SRR1 */ \ 236 mfspr r12,SPRN_SRR1; /* and SRR1 */ \
@@ -553,6 +571,7 @@ slb_miss_user_pseries:
553 * Vectors for the FWNMI option. Share common code. 571 * Vectors for the FWNMI option. Share common code.
554 */ 572 */
555 .globl system_reset_fwnmi 573 .globl system_reset_fwnmi
574 .align 7
556system_reset_fwnmi: 575system_reset_fwnmi:
557 HMT_MEDIUM 576 HMT_MEDIUM
558 mtspr SPRN_SPRG1,r13 /* save r13 */ 577 mtspr SPRN_SPRG1,r13 /* save r13 */
@@ -560,6 +579,7 @@ system_reset_fwnmi:
560 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) 579 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
561 580
562 .globl machine_check_fwnmi 581 .globl machine_check_fwnmi
582 .align 7
563machine_check_fwnmi: 583machine_check_fwnmi:
564 HMT_MEDIUM 584 HMT_MEDIUM
565 mtspr SPRN_SPRG1,r13 /* save r13 */ 585 mtspr SPRN_SPRG1,r13 /* save r13 */
@@ -726,7 +746,8 @@ iSeries_secondary_smp_loop:
726decrementer_iSeries_masked: 746decrementer_iSeries_masked:
727 li r11,1 747 li r11,1
728 stb r11,PACALPPACA+LPPACADECRINT(r13) 748 stb r11,PACALPPACA+LPPACADECRINT(r13)
729 lwz r12,PACADEFAULTDECR(r13) 749 LOADBASE(r12,tb_ticks_per_jiffy)
750 lwz r12,OFF(tb_ticks_per_jiffy)(r12)
730 mtspr SPRN_DEC,r12 751 mtspr SPRN_DEC,r12
731 /* fall through */ 752 /* fall through */
732 753
@@ -1345,7 +1366,7 @@ _GLOBAL(do_stab_bolted)
1345 * fixed address (the linker can't compute (u64)&initial_stab >> 1366 * fixed address (the linker can't compute (u64)&initial_stab >>
1346 * PAGE_SHIFT). 1367 * PAGE_SHIFT).
1347 */ 1368 */
1348 . = STAB0_PHYS_ADDR /* 0x6000 */ 1369 . = STAB0_OFFSET /* 0x6000 */
1349 .globl initial_stab 1370 .globl initial_stab
1350initial_stab: 1371initial_stab:
1351 .space 4096 1372 .space 4096
@@ -1485,11 +1506,13 @@ _STATIC(__mmu_off)
1485 * 1506 *
1486 */ 1507 */
1487_GLOBAL(__start_initialization_multiplatform) 1508_GLOBAL(__start_initialization_multiplatform)
1509#ifdef CONFIG_PPC_MULTIPLATFORM
1488 /* 1510 /*
1489 * Are we booted from a PROM Of-type client-interface ? 1511 * Are we booted from a PROM Of-type client-interface ?
1490 */ 1512 */
1491 cmpldi cr0,r5,0 1513 cmpldi cr0,r5,0
1492 bne .__boot_from_prom /* yes -> prom */ 1514 bne .__boot_from_prom /* yes -> prom */
1515#endif
1493 1516
1494 /* Save parameters */ 1517 /* Save parameters */
1495 mr r31,r3 1518 mr r31,r3
@@ -1510,6 +1533,7 @@ _GLOBAL(__start_initialization_multiplatform)
1510 bl .__mmu_off 1533 bl .__mmu_off
1511 b .__after_prom_start 1534 b .__after_prom_start
1512 1535
1536#ifdef CONFIG_PPC_MULTIPLATFORM
1513_STATIC(__boot_from_prom) 1537_STATIC(__boot_from_prom)
1514 /* Save parameters */ 1538 /* Save parameters */
1515 mr r31,r3 1539 mr r31,r3
@@ -1542,6 +1566,7 @@ _STATIC(__boot_from_prom)
1542 bl .prom_init 1566 bl .prom_init
1543 /* We never return */ 1567 /* We never return */
1544 trap 1568 trap
1569#endif
1545 1570
1546/* 1571/*
1547 * At this point, r3 contains the physical address we are running at, 1572 * At this point, r3 contains the physical address we are running at,
@@ -1550,7 +1575,7 @@ _STATIC(__boot_from_prom)
1550_STATIC(__after_prom_start) 1575_STATIC(__after_prom_start)
1551 1576
1552/* 1577/*
1553 * We need to run with __start at physical address 0. 1578 * We need to run with __start at physical address PHYSICAL_START.
1554 * This will leave some code in the first 256B of 1579 * This will leave some code in the first 256B of
1555 * real memory, which are reserved for software use. 1580 * real memory, which are reserved for software use.
1556 * The remainder of the first page is loaded with the fixed 1581 * The remainder of the first page is loaded with the fixed
@@ -1565,7 +1590,7 @@ _STATIC(__after_prom_start)
1565 mr r26,r3 1590 mr r26,r3
1566 SET_REG_TO_CONST(r27,KERNELBASE) 1591 SET_REG_TO_CONST(r27,KERNELBASE)
1567 1592
1568 li r3,0 /* target addr */ 1593 LOADADDR(r3, PHYSICAL_START) /* target addr */
1569 1594
1570 // XXX FIXME: Use phys returned by OF (r30) 1595 // XXX FIXME: Use phys returned by OF (r30)
1571 add r4,r27,r26 /* source addr */ 1596 add r4,r27,r26 /* source addr */
@@ -1846,7 +1871,7 @@ _STATIC(start_here_multiplatform)
1846 mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ 1871 mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */
1847 add r13,r13,r24 /* for this processor. */ 1872 add r13,r13,r24 /* for this processor. */
1848 add r13,r13,r26 /* convert to physical addr */ 1873 add r13,r13,r26 /* convert to physical addr */
1849 mtspr SPRN_SPRG3,r13 /* PPPBBB: Temp... -Peter */ 1874 mtspr SPRN_SPRG3,r13
1850 1875
1851 /* Do very early kernel initializations, including initial hash table, 1876 /* Do very early kernel initializations, including initial hash table,
1852 * stab and slb setup before we turn on relocation. */ 1877 * stab and slb setup before we turn on relocation. */
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
new file mode 100644
index 000000000000..e47d40ac6f39
--- /dev/null
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -0,0 +1,396 @@
1/*
2 * IBM PowerPC IBM eBus Infrastructure Support.
3 *
4 * Copyright (c) 2005 IBM Corporation
5 * Heiko J Schick <schickhj@de.ibm.com>
6 *
7 * All rights reserved.
8 *
9 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
10 * BSD.
11 *
12 * OpenIB BSD License
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are met:
16 *
17 * Redistributions of source code must retain the above copyright notice, this
18 * list of conditions and the following disclaimer.
19 *
20 * Redistributions in binary form must reproduce the above copyright notice,
21 * this list of conditions and the following disclaimer in the documentation
22 * and/or other materials
23 * provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
32 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
33 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#include <linux/init.h>
39#include <linux/console.h>
40#include <linux/kobject.h>
41#include <linux/dma-mapping.h>
42#include <linux/interrupt.h>
43#include <asm/ibmebus.h>
44#include <asm/abs_addr.h>
45
46static struct ibmebus_dev ibmebus_bus_device = { /* fake "parent" device */
47 .name = ibmebus_bus_device.ofdev.dev.bus_id,
48 .ofdev.dev.bus_id = "ibmebus",
49 .ofdev.dev.bus = &ibmebus_bus_type,
50};
51
52static void *ibmebus_alloc_coherent(struct device *dev,
53 size_t size,
54 dma_addr_t *dma_handle,
55 gfp_t flag)
56{
57 void *mem;
58
59 mem = kmalloc(size, flag);
60 *dma_handle = (dma_addr_t)mem;
61
62 return mem;
63}
64
65static void ibmebus_free_coherent(struct device *dev,
66 size_t size, void *vaddr,
67 dma_addr_t dma_handle)
68{
69 kfree(vaddr);
70}
71
72static dma_addr_t ibmebus_map_single(struct device *dev,
73 void *ptr,
74 size_t size,
75 enum dma_data_direction direction)
76{
77 return (dma_addr_t)(ptr);
78}
79
80static void ibmebus_unmap_single(struct device *dev,
81 dma_addr_t dma_addr,
82 size_t size,
83 enum dma_data_direction direction)
84{
85 return;
86}
87
88static int ibmebus_map_sg(struct device *dev,
89 struct scatterlist *sg,
90 int nents, enum dma_data_direction direction)
91{
92 int i;
93
94 for (i = 0; i < nents; i++) {
95 sg[i].dma_address = (dma_addr_t)page_address(sg[i].page)
96 + sg[i].offset;
97 sg[i].dma_length = sg[i].length;
98 }
99
100 return nents;
101}
102
103static void ibmebus_unmap_sg(struct device *dev,
104 struct scatterlist *sg,
105 int nents, enum dma_data_direction direction)
106{
107 return;
108}
109
110static int ibmebus_dma_supported(struct device *dev, u64 mask)
111{
112 return 1;
113}
114
115struct dma_mapping_ops ibmebus_dma_ops = {
116 .alloc_coherent = ibmebus_alloc_coherent,
117 .free_coherent = ibmebus_free_coherent,
118 .map_single = ibmebus_map_single,
119 .unmap_single = ibmebus_unmap_single,
120 .map_sg = ibmebus_map_sg,
121 .unmap_sg = ibmebus_unmap_sg,
122 .dma_supported = ibmebus_dma_supported,
123};
124
125static int ibmebus_bus_probe(struct device *dev)
126{
127 struct ibmebus_dev *ibmebusdev = to_ibmebus_dev(dev);
128 struct ibmebus_driver *ibmebusdrv = to_ibmebus_driver(dev->driver);
129 const struct of_device_id *id;
130 int error = -ENODEV;
131
132 if (!ibmebusdrv->probe)
133 return error;
134
135 id = of_match_device(ibmebusdrv->id_table, &ibmebusdev->ofdev);
136 if (id) {
137 error = ibmebusdrv->probe(ibmebusdev, id);
138 }
139
140 return error;
141}
142
143static int ibmebus_bus_remove(struct device *dev)
144{
145 struct ibmebus_dev *ibmebusdev = to_ibmebus_dev(dev);
146 struct ibmebus_driver *ibmebusdrv = to_ibmebus_driver(dev->driver);
147
148 if (ibmebusdrv->remove) {
149 return ibmebusdrv->remove(ibmebusdev);
150 }
151
152 return 0;
153}
154
155static void __devinit ibmebus_dev_release(struct device *dev)
156{
157 of_node_put(to_ibmebus_dev(dev)->ofdev.node);
158 kfree(to_ibmebus_dev(dev));
159}
160
161static ssize_t ibmebusdev_show_name(struct device *dev,
162 struct device_attribute *attr, char *buf)
163{
164 return sprintf(buf, "%s\n", to_ibmebus_dev(dev)->name);
165}
166static DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, ibmebusdev_show_name,
167 NULL);
168
169static struct ibmebus_dev* __devinit ibmebus_register_device_common(
170 struct ibmebus_dev *dev, char *name)
171{
172 int err = 0;
173
174 dev->name = name;
175 dev->ofdev.dev.parent = &ibmebus_bus_device.ofdev.dev;
176 dev->ofdev.dev.bus = &ibmebus_bus_type;
177 dev->ofdev.dev.release = ibmebus_dev_release;
178
179 /* An ibmebusdev is based on a of_device. We have to change the
180 * bus type to use our own DMA mapping operations.
181 */
182 if ((err = of_device_register(&dev->ofdev)) != 0) {
183 printk(KERN_ERR "%s: failed to register device (%d).\n",
184 __FUNCTION__, err);
185 return NULL;
186 }
187
188 device_create_file(&dev->ofdev.dev, &dev_attr_name);
189
190 return dev;
191}
192
193static struct ibmebus_dev* __devinit ibmebus_register_device_node(
194 struct device_node *dn)
195{
196 struct ibmebus_dev *dev;
197 char *loc_code;
198 int length;
199
200 loc_code = (char *)get_property(dn, "ibm,loc-code", NULL);
201 if (!loc_code) {
202 printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n",
203 __FUNCTION__, dn->name ? dn->name : "<unknown>");
204 return NULL;
205 }
206
207 if (strlen(loc_code) == 0) {
208 printk(KERN_WARNING "%s: 'ibm,loc-code' is invalid\n",
209 __FUNCTION__);
210 return NULL;
211 }
212
213 dev = kmalloc(sizeof(struct ibmebus_dev), GFP_KERNEL);
214 if (!dev) {
215 return NULL;
216 }
217 memset(dev, 0, sizeof(struct ibmebus_dev));
218
219 dev->ofdev.node = of_node_get(dn);
220
221 length = strlen(loc_code);
222 memcpy(dev->ofdev.dev.bus_id, loc_code
223 + (length - min(length, BUS_ID_SIZE - 1)),
224 min(length, BUS_ID_SIZE - 1));
225
226 /* Register with generic device framework. */
227 if (ibmebus_register_device_common(dev, dn->name) == NULL) {
228 kfree(dev);
229 return NULL;
230 }
231
232 return dev;
233}
234
235static void ibmebus_probe_of_nodes(char* name)
236{
237 struct device_node *dn = NULL;
238
239 while ((dn = of_find_node_by_name(dn, name))) {
240 if (ibmebus_register_device_node(dn) == NULL) {
241 of_node_put(dn);
242
243 return;
244 }
245 }
246
247 of_node_put(dn);
248
249 return;
250}
251
252static void ibmebus_add_devices_by_id(struct of_device_id *idt)
253{
254 while (strlen(idt->name) > 0) {
255 ibmebus_probe_of_nodes(idt->name);
256 idt++;
257 }
258
259 return;
260}
261
262static int ibmebus_match_helper(struct device *dev, void *data)
263{
264 if (strcmp((char*)data, to_ibmebus_dev(dev)->name) == 0)
265 return 1;
266
267 return 0;
268}
269
270static int ibmebus_unregister_device(struct device *dev)
271{
272 device_remove_file(dev, &dev_attr_name);
273 of_device_unregister(to_of_device(dev));
274
275 return 0;
276}
277
278static void ibmebus_remove_devices_by_id(struct of_device_id *idt)
279{
280 struct device *dev;
281
282 while (strlen(idt->name) > 0) {
283 while ((dev = bus_find_device(&ibmebus_bus_type, NULL,
284 (void*)idt->name,
285 ibmebus_match_helper))) {
286 ibmebus_unregister_device(dev);
287 }
288 idt++;
289
290 }
291
292 return;
293}
294
295int ibmebus_register_driver(struct ibmebus_driver *drv)
296{
297 int err = 0;
298
299 drv->driver.name = drv->name;
300 drv->driver.bus = &ibmebus_bus_type;
301 drv->driver.probe = ibmebus_bus_probe;
302 drv->driver.remove = ibmebus_bus_remove;
303
304 if ((err = driver_register(&drv->driver) != 0))
305 return err;
306
307 ibmebus_add_devices_by_id(drv->id_table);
308
309 return 0;
310}
311EXPORT_SYMBOL(ibmebus_register_driver);
312
313void ibmebus_unregister_driver(struct ibmebus_driver *drv)
314{
315 driver_unregister(&drv->driver);
316 ibmebus_remove_devices_by_id(drv->id_table);
317}
318EXPORT_SYMBOL(ibmebus_unregister_driver);
319
320int ibmebus_request_irq(struct ibmebus_dev *dev,
321 u32 ist,
322 irqreturn_t (*handler)(int, void*, struct pt_regs *),
323 unsigned long irq_flags, const char * devname,
324 void *dev_id)
325{
326 unsigned int irq = virt_irq_create_mapping(ist);
327
328 if (irq == NO_IRQ)
329 return -EINVAL;
330
331 irq = irq_offset_up(irq);
332
333 return request_irq(irq, handler,
334 irq_flags, devname, dev_id);
335}
336EXPORT_SYMBOL(ibmebus_request_irq);
337
338void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id)
339{
340 unsigned int irq = virt_irq_create_mapping(ist);
341
342 irq = irq_offset_up(irq);
343 free_irq(irq, dev_id);
344
345 return;
346}
347EXPORT_SYMBOL(ibmebus_free_irq);
348
349static int ibmebus_bus_match(struct device *dev, struct device_driver *drv)
350{
351 const struct ibmebus_dev *ebus_dev = to_ibmebus_dev(dev);
352 struct ibmebus_driver *ebus_drv = to_ibmebus_driver(drv);
353 const struct of_device_id *ids = ebus_drv->id_table;
354 const struct of_device_id *found_id;
355
356 if (!ids)
357 return 0;
358
359 found_id = of_match_device(ids, &ebus_dev->ofdev);
360 if (found_id)
361 return 1;
362
363 return 0;
364}
365
366struct bus_type ibmebus_bus_type = {
367 .name = "ibmebus",
368 .match = ibmebus_bus_match,
369};
370EXPORT_SYMBOL(ibmebus_bus_type);
371
372static int __init ibmebus_bus_init(void)
373{
374 int err;
375
376 printk(KERN_INFO "IBM eBus Device Driver\n");
377
378 err = bus_register(&ibmebus_bus_type);
379 if (err) {
380 printk(KERN_ERR ":%s: failed to register IBM eBus.\n",
381 __FUNCTION__);
382 return err;
383 }
384
385 err = device_register(&ibmebus_bus_device.ofdev.dev);
386 if (err) {
387 printk(KERN_WARNING "%s: device_register returned %i\n",
388 __FUNCTION__, err);
389 bus_unregister(&ibmebus_bus_type);
390
391 return err;
392 }
393
394 return 0;
395}
396__initcall(ibmebus_bus_init);
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 5a71ed9612fe..5651032d8706 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -31,7 +31,6 @@
31 * to reduce code space and undefined function references. 31 * to reduce code space and undefined function references.
32 */ 32 */
33 33
34#include <linux/errno.h>
35#include <linux/module.h> 34#include <linux/module.h>
36#include <linux/threads.h> 35#include <linux/threads.h>
37#include <linux/kernel_stat.h> 36#include <linux/kernel_stat.h>
@@ -44,18 +43,12 @@
44#include <linux/config.h> 43#include <linux/config.h>
45#include <linux/init.h> 44#include <linux/init.h>
46#include <linux/slab.h> 45#include <linux/slab.h>
47#include <linux/pci.h>
48#include <linux/delay.h> 46#include <linux/delay.h>
49#include <linux/irq.h> 47#include <linux/irq.h>
50#include <linux/proc_fs.h>
51#include <linux/random.h>
52#include <linux/seq_file.h> 48#include <linux/seq_file.h>
53#include <linux/cpumask.h> 49#include <linux/cpumask.h>
54#include <linux/profile.h> 50#include <linux/profile.h>
55#include <linux/bitops.h> 51#include <linux/bitops.h>
56#ifdef CONFIG_PPC64
57#include <linux/kallsyms.h>
58#endif
59 52
60#include <asm/uaccess.h> 53#include <asm/uaccess.h>
61#include <asm/system.h> 54#include <asm/system.h>
@@ -66,8 +59,7 @@
66#include <asm/prom.h> 59#include <asm/prom.h>
67#include <asm/ptrace.h> 60#include <asm/ptrace.h>
68#include <asm/machdep.h> 61#include <asm/machdep.h>
69#ifdef CONFIG_PPC64 62#ifdef CONFIG_PPC_ISERIES
70#include <asm/iseries/it_lp_queue.h>
71#include <asm/paca.h> 63#include <asm/paca.h>
72#endif 64#endif
73 65
@@ -78,10 +70,6 @@ EXPORT_SYMBOL(__irq_offset_value);
78 70
79static int ppc_spurious_interrupts; 71static int ppc_spurious_interrupts;
80 72
81#if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP)
82extern void iSeries_smp_message_recv(struct pt_regs *);
83#endif
84
85#ifdef CONFIG_PPC32 73#ifdef CONFIG_PPC32
86#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) 74#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
87 75
@@ -195,49 +183,6 @@ void fixup_irqs(cpumask_t map)
195} 183}
196#endif 184#endif
197 185
198#ifdef CONFIG_PPC_ISERIES
199void do_IRQ(struct pt_regs *regs)
200{
201 struct paca_struct *lpaca;
202
203 irq_enter();
204
205#ifdef CONFIG_DEBUG_STACKOVERFLOW
206 /* Debugging check for stack overflow: is there less than 2KB free? */
207 {
208 long sp;
209
210 sp = __get_SP() & (THREAD_SIZE-1);
211
212 if (unlikely(sp < (sizeof(struct thread_info) + 2048))) {
213 printk("do_IRQ: stack overflow: %ld\n",
214 sp - sizeof(struct thread_info));
215 dump_stack();
216 }
217 }
218#endif
219
220 lpaca = get_paca();
221#ifdef CONFIG_SMP
222 if (lpaca->lppaca.int_dword.fields.ipi_cnt) {
223 lpaca->lppaca.int_dword.fields.ipi_cnt = 0;
224 iSeries_smp_message_recv(regs);
225 }
226#endif /* CONFIG_SMP */
227 if (hvlpevent_is_pending())
228 process_hvlpevents(regs);
229
230 irq_exit();
231
232 if (lpaca->lppaca.int_dword.fields.decr_int) {
233 lpaca->lppaca.int_dword.fields.decr_int = 0;
234 /* Signal a fake decrementer interrupt */
235 timer_interrupt(regs);
236 }
237}
238
239#else /* CONFIG_PPC_ISERIES */
240
241void do_IRQ(struct pt_regs *regs) 186void do_IRQ(struct pt_regs *regs)
242{ 187{
243 int irq; 188 int irq;
@@ -286,16 +231,24 @@ void do_IRQ(struct pt_regs *regs)
286 } else 231 } else
287#endif 232#endif
288 __do_IRQ(irq, regs); 233 __do_IRQ(irq, regs);
289 } else 234 } else if (irq != -2)
290#ifdef CONFIG_PPC32 235 /* That's not SMP safe ... but who cares ? */
291 if (irq != -2) 236 ppc_spurious_interrupts++;
292#endif 237
293 /* That's not SMP safe ... but who cares ? */
294 ppc_spurious_interrupts++;
295 irq_exit(); 238 irq_exit();
296}
297 239
298#endif /* CONFIG_PPC_ISERIES */ 240#ifdef CONFIG_PPC_ISERIES
241 {
242 struct paca_struct *lpaca = get_paca();
243
244 if (lpaca->lppaca.int_dword.fields.decr_int) {
245 lpaca->lppaca.int_dword.fields.decr_int = 0;
246 /* Signal a fake decrementer interrupt */
247 timer_interrupt(regs);
248 }
249 }
250#endif
251}
299 252
300void __init init_IRQ(void) 253void __init init_IRQ(void)
301{ 254{
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
new file mode 100644
index 000000000000..f970ace208d3
--- /dev/null
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -0,0 +1,557 @@
1#include <linux/config.h>
2#include <linux/kernel.h>
3#include <linux/serial.h>
4#include <linux/serial_8250.h>
5#include <linux/serial_core.h>
6#include <linux/console.h>
7#include <linux/pci.h>
8#include <asm/io.h>
9#include <asm/mmu.h>
10#include <asm/prom.h>
11#include <asm/serial.h>
12#include <asm/udbg.h>
13#include <asm/pci-bridge.h>
14#include <asm/ppc-pci.h>
15
16#undef DEBUG
17
18#ifdef DEBUG
19#define DBG(fmt...) do { printk(fmt); } while(0)
20#else
21#define DBG(fmt...) do { } while(0)
22#endif
23
24#define MAX_LEGACY_SERIAL_PORTS 8
25
26static struct plat_serial8250_port
27legacy_serial_ports[MAX_LEGACY_SERIAL_PORTS+1];
28static struct legacy_serial_info {
29 struct device_node *np;
30 unsigned int speed;
31 unsigned int clock;
32 phys_addr_t taddr;
33} legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS];
34static unsigned int legacy_serial_count;
35static int legacy_serial_console = -1;
36
37static int __init add_legacy_port(struct device_node *np, int want_index,
38 int iotype, phys_addr_t base,
39 phys_addr_t taddr, unsigned long irq,
40 unsigned int flags)
41{
42 u32 *clk, *spd, clock = BASE_BAUD * 16;
43 int index;
44
45 /* get clock freq. if present */
46 clk = (u32 *)get_property(np, "clock-frequency", NULL);
47 if (clk && *clk)
48 clock = *clk;
49
50 /* get default speed if present */
51 spd = (u32 *)get_property(np, "current-speed", NULL);
52
53 /* If we have a location index, then try to use it */
54 if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS)
55 index = want_index;
56 else
57 index = legacy_serial_count;
58
59 /* if our index is still out of range, that mean that
60 * array is full, we could scan for a free slot but that
61 * make little sense to bother, just skip the port
62 */
63 if (index >= MAX_LEGACY_SERIAL_PORTS)
64 return -1;
65 if (index >= legacy_serial_count)
66 legacy_serial_count = index + 1;
67
68 /* Check if there is a port who already claimed our slot */
69 if (legacy_serial_infos[index].np != 0) {
70 /* if we still have some room, move it, else override */
71 if (legacy_serial_count < MAX_LEGACY_SERIAL_PORTS) {
72 printk(KERN_INFO "Moved legacy port %d -> %d\n",
73 index, legacy_serial_count);
74 legacy_serial_ports[legacy_serial_count] =
75 legacy_serial_ports[index];
76 legacy_serial_infos[legacy_serial_count] =
77 legacy_serial_infos[index];
78 legacy_serial_count++;
79 } else {
80 printk(KERN_INFO "Replacing legacy port %d\n", index);
81 }
82 }
83
84 /* Now fill the entry */
85 memset(&legacy_serial_ports[index], 0,
86 sizeof(struct plat_serial8250_port));
87 if (iotype == UPIO_PORT)
88 legacy_serial_ports[index].iobase = base;
89 else
90 legacy_serial_ports[index].mapbase = base;
91 legacy_serial_ports[index].iotype = iotype;
92 legacy_serial_ports[index].uartclk = clock;
93 legacy_serial_ports[index].irq = irq;
94 legacy_serial_ports[index].flags = flags;
95 legacy_serial_infos[index].taddr = taddr;
96 legacy_serial_infos[index].np = of_node_get(np);
97 legacy_serial_infos[index].clock = clock;
98 legacy_serial_infos[index].speed = spd ? *spd : 0;
99
100 printk(KERN_INFO "Found legacy serial port %d for %s\n",
101 index, np->full_name);
102 printk(KERN_INFO " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n",
103 (iotype == UPIO_PORT) ? "port" : "mem",
104 (unsigned long long)base, (unsigned long long)taddr, irq,
105 legacy_serial_ports[index].uartclk,
106 legacy_serial_infos[index].speed);
107
108 return index;
109}
110
111static int __init add_legacy_soc_port(struct device_node *np,
112 struct device_node *soc_dev)
113{
114 phys_addr_t addr;
115 u32 *addrp;
116 unsigned int flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
117
118 /* We only support ports that have a clock frequency properly
119 * encoded in the device-tree.
120 */
121 if (get_property(np, "clock-frequency", NULL) == NULL)
122 return -1;
123
124 /* Get the address */
125 addrp = of_get_address(soc_dev, 0, NULL, NULL);
126 if (addrp == NULL)
127 return -1;
128
129 addr = of_translate_address(soc_dev, addrp);
130
131 /* Add port, irq will be dealt with later. We passed a translated
132 * IO port value. It will be fixed up later along with the irq
133 */
134 return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags);
135}
136
137#ifdef CONFIG_ISA
138static int __init add_legacy_isa_port(struct device_node *np,
139 struct device_node *isa_brg)
140{
141 u32 *reg;
142 char *typep;
143 int index = -1;
144 phys_addr_t taddr;
145
146 /* Get the ISA port number */
147 reg = (u32 *)get_property(np, "reg", NULL);
148 if (reg == NULL)
149 return -1;
150
151 /* Verify it's an IO port, we don't support anything else */
152 if (!(reg[0] & 0x00000001))
153 return -1;
154
155 /* Now look for an "ibm,aix-loc" property that gives us ordering
156 * if any...
157 */
158 typep = (char *)get_property(np, "ibm,aix-loc", NULL);
159
160 /* If we have a location index, then use it */
161 if (typep && *typep == 'S')
162 index = simple_strtol(typep+1, NULL, 0) - 1;
163
164 /* Translate ISA address */
165 taddr = of_translate_address(np, reg);
166
167 /* Add port, irq will be dealt with later */
168 return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, NO_IRQ, UPF_BOOT_AUTOCONF);
169
170}
171#endif
172
173#ifdef CONFIG_PCI
174static int __init add_legacy_pci_port(struct device_node *np,
175 struct device_node *pci_dev)
176{
177 phys_addr_t addr, base;
178 u32 *addrp;
179 unsigned int flags;
180 int iotype, index = -1, lindex = 0;
181
182 /* We only support ports that have a clock frequency properly
183 * encoded in the device-tree (that is have an fcode). Anything
184 * else can't be used that early and will be normally probed by
185 * the generic 8250_pci driver later on. The reason is that 8250
186 * compatible UARTs on PCI need all sort of quirks (port offsets
187 * etc...) that this code doesn't know about
188 */
189 if (get_property(np, "clock-frequency", NULL) == NULL)
190 return -1;
191
192 /* Get the PCI address. Assume BAR 0 */
193 addrp = of_get_pci_address(pci_dev, 0, NULL, &flags);
194 if (addrp == NULL)
195 return -1;
196
197 /* We only support BAR 0 for now */
198 iotype = (flags & IORESOURCE_MEM) ? UPIO_MEM : UPIO_PORT;
199 addr = of_translate_address(pci_dev, addrp);
200
201 /* Set the IO base to the same as the translated address for MMIO,
202 * or to the domain local IO base for PIO (it will be fixed up later)
203 */
204 if (iotype == UPIO_MEM)
205 base = addr;
206 else
207 base = addrp[2];
208
209 /* Try to guess an index... If we have subdevices of the pci dev,
210 * we get to their "reg" property
211 */
212 if (np != pci_dev) {
213 u32 *reg = (u32 *)get_property(np, "reg", NULL);
214 if (reg && (*reg < 4))
215 index = lindex = *reg;
216 }
217
218 /* Local index means it's the Nth port in the PCI chip. Unfortunately
219 * the offset to add here is device specific. We know about those
220 * EXAR ports and we default to the most common case. If your UART
221 * doesn't work for these settings, you'll have to add your own special
222 * cases here
223 */
224 if (device_is_compatible(pci_dev, "pci13a8,152") ||
225 device_is_compatible(pci_dev, "pci13a8,154") ||
226 device_is_compatible(pci_dev, "pci13a8,158")) {
227 addr += 0x200 * lindex;
228 base += 0x200 * lindex;
229 } else {
230 addr += 8 * lindex;
231 base += 8 * lindex;
232 }
233
234 /* Add port, irq will be dealt with later. We passed a translated
235 * IO port value. It will be fixed up later along with the irq
236 */
237 return add_legacy_port(np, index, iotype, base, addr, NO_IRQ, UPF_BOOT_AUTOCONF);
238}
239#endif
240
241/*
242 * This is called very early, as part of setup_system() or eventually
243 * setup_arch(), basically before anything else in this file. This function
244 * will try to build a list of all the available 8250-compatible serial ports
245 * in the machine using the Open Firmware device-tree. It currently only deals
246 * with ISA and PCI busses but could be extended. It allows a very early boot
247 * console to be initialized, that list is also used later to provide 8250 with
248 * the machine non-PCI ports and to properly pick the default console port
249 */
250void __init find_legacy_serial_ports(void)
251{
252 struct device_node *np, *stdout = NULL;
253 char *path;
254 int index;
255
256 DBG(" -> find_legacy_serial_port()\n");
257
258 /* Now find out if one of these is out firmware console */
259 path = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
260 if (path != NULL) {
261 stdout = of_find_node_by_path(path);
262 if (stdout)
263 DBG("stdout is %s\n", stdout->full_name);
264 } else {
265 DBG(" no linux,stdout-path !\n");
266 }
267
268 /* First fill our array with SOC ports */
269 for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) {
270 struct device_node *soc = of_get_parent(np);
271 if (soc && !strcmp(soc->type, "soc")) {
272 index = add_legacy_soc_port(np, np);
273 if (index >= 0 && np == stdout)
274 legacy_serial_console = index;
275 }
276 of_node_put(soc);
277 }
278
279#ifdef CONFIG_ISA
280 /* First fill our array with ISA ports */
281 for (np = NULL; (np = of_find_node_by_type(np, "serial"));) {
282 struct device_node *isa = of_get_parent(np);
283 if (isa && !strcmp(isa->name, "isa")) {
284 index = add_legacy_isa_port(np, isa);
285 if (index >= 0 && np == stdout)
286 legacy_serial_console = index;
287 }
288 of_node_put(isa);
289 }
290#endif
291
292#ifdef CONFIG_PCI
293 /* Next, try to locate PCI ports */
294 for (np = NULL; (np = of_find_all_nodes(np));) {
295 struct device_node *pci, *parent = of_get_parent(np);
296 if (parent && !strcmp(parent->name, "isa")) {
297 of_node_put(parent);
298 continue;
299 }
300 if (strcmp(np->name, "serial") && strcmp(np->type, "serial")) {
301 of_node_put(parent);
302 continue;
303 }
304 /* Check for known pciclass, and also check wether we have
305 * a device with child nodes for ports or not
306 */
307 if (device_is_compatible(np, "pciclass,0700") ||
308 device_is_compatible(np, "pciclass,070002"))
309 pci = np;
310 else if (device_is_compatible(parent, "pciclass,0700") ||
311 device_is_compatible(parent, "pciclass,070002"))
312 pci = parent;
313 else {
314 of_node_put(parent);
315 continue;
316 }
317 index = add_legacy_pci_port(np, pci);
318 if (index >= 0 && np == stdout)
319 legacy_serial_console = index;
320 of_node_put(parent);
321 }
322#endif
323
324 DBG("legacy_serial_console = %d\n", legacy_serial_console);
325
326 /* udbg is 64 bits only for now, that will change soon though ... */
327 while (legacy_serial_console >= 0) {
328 struct legacy_serial_info *info =
329 &legacy_serial_infos[legacy_serial_console];
330 void __iomem *addr;
331
332 if (info->taddr == 0)
333 break;
334 addr = ioremap(info->taddr, 0x1000);
335 if (addr == NULL)
336 break;
337 if (info->speed == 0)
338 info->speed = udbg_probe_uart_speed(addr, info->clock);
339 DBG("default console speed = %d\n", info->speed);
340 udbg_init_uart(addr, info->speed, info->clock);
341 break;
342 }
343
344 DBG(" <- find_legacy_serial_port()\n");
345}
346
347static struct platform_device serial_device = {
348 .name = "serial8250",
349 .id = PLAT8250_DEV_PLATFORM,
350 .dev = {
351 .platform_data = legacy_serial_ports,
352 },
353};
354
355static void __init fixup_port_irq(int index,
356 struct device_node *np,
357 struct plat_serial8250_port *port)
358{
359 DBG("fixup_port_irq(%d)\n", index);
360
361 /* Check for interrupts in that node */
362 if (np->n_intrs > 0) {
363 port->irq = np->intrs[0].line;
364 DBG(" port %d (%s), irq=%d\n",
365 index, np->full_name, port->irq);
366 return;
367 }
368
369 /* Check for interrupts in the parent */
370 np = of_get_parent(np);
371 if (np == NULL)
372 return;
373
374 if (np->n_intrs > 0) {
375 port->irq = np->intrs[0].line;
376 DBG(" port %d (%s), irq=%d\n",
377 index, np->full_name, port->irq);
378 }
379 of_node_put(np);
380}
381
382static void __init fixup_port_pio(int index,
383 struct device_node *np,
384 struct plat_serial8250_port *port)
385{
386#ifdef CONFIG_PCI
387 struct pci_controller *hose;
388
389 DBG("fixup_port_pio(%d)\n", index);
390
391 hose = pci_find_hose_for_OF_device(np);
392 if (hose) {
393 unsigned long offset = (unsigned long)hose->io_base_virt -
394#ifdef CONFIG_PPC64
395 pci_io_base;
396#else
397 isa_io_base;
398#endif
399 DBG("port %d, IO %lx -> %lx\n",
400 index, port->iobase, port->iobase + offset);
401 port->iobase += offset;
402 }
403#endif
404}
405
406static void __init fixup_port_mmio(int index,
407 struct device_node *np,
408 struct plat_serial8250_port *port)
409{
410 DBG("fixup_port_mmio(%d)\n", index);
411
412 port->membase = ioremap(port->mapbase, 0x100);
413}
414
415/*
416 * This is called as an arch initcall, hopefully before the PCI bus is
417 * probed and/or the 8250 driver loaded since we need to register our
418 * platform devices before 8250 PCI ones are detected as some of them
419 * must properly "override" the platform ones.
420 *
421 * This function fixes up the interrupt value for platform ports as it
422 * couldn't be done earlier before interrupt maps have been parsed. It
423 * also "corrects" the IO address for PIO ports for the same reason,
424 * since earlier, the PHBs virtual IO space wasn't assigned yet. It then
425 * registers all those platform ports for use by the 8250 driver when it
426 * finally loads.
427 */
428static int __init serial_dev_init(void)
429{
430 int i;
431
432 if (legacy_serial_count == 0)
433 return -ENODEV;
434
435 /*
436 * Before we register the platfrom serial devices, we need
437 * to fixup their interrutps and their IO ports.
438 */
439 DBG("Fixing serial ports interrupts and IO ports ...\n");
440
441 for (i = 0; i < legacy_serial_count; i++) {
442 struct plat_serial8250_port *port = &legacy_serial_ports[i];
443 struct device_node *np = legacy_serial_infos[i].np;
444
445 if (port->irq == NO_IRQ)
446 fixup_port_irq(i, np, port);
447 if (port->iotype == UPIO_PORT)
448 fixup_port_pio(i, np, port);
449 if (port->iotype == UPIO_MEM)
450 fixup_port_mmio(i, np, port);
451 }
452
453 DBG("Registering platform serial ports\n");
454
455 return platform_device_register(&serial_device);
456}
457arch_initcall(serial_dev_init);
458
459
460/*
461 * This is called very early, as part of console_init() (typically just after
462 * time_init()). This function is respondible for trying to find a good
463 * default console on serial ports. It tries to match the open firmware
464 * default output with one of the available serial console drivers, either
465 * one of the platform serial ports that have been probed earlier by
466 * find_legacy_serial_ports() or some more platform specific ones.
467 */
468static int __init check_legacy_serial_console(void)
469{
470 struct device_node *prom_stdout = NULL;
471 int speed = 0, offset = 0;
472 char *name;
473 u32 *spd;
474
475 DBG(" -> check_legacy_serial_console()\n");
476
477 /* The user has requested a console so this is already set up. */
478 if (strstr(saved_command_line, "console=")) {
479 DBG(" console was specified !\n");
480 return -EBUSY;
481 }
482
483 if (!of_chosen) {
484 DBG(" of_chosen is NULL !\n");
485 return -ENODEV;
486 }
487
488 if (legacy_serial_console < 0) {
489 DBG(" legacy_serial_console not found !\n");
490 return -ENODEV;
491 }
492 /* We are getting a weird phandle from OF ... */
493 /* ... So use the full path instead */
494 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
495 if (name == NULL) {
496 DBG(" no linux,stdout-path !\n");
497 return -ENODEV;
498 }
499 prom_stdout = of_find_node_by_path(name);
500 if (!prom_stdout) {
501 DBG(" can't find stdout package %s !\n", name);
502 return -ENODEV;
503 }
504 DBG("stdout is %s\n", prom_stdout->full_name);
505
506 name = (char *)get_property(prom_stdout, "name", NULL);
507 if (!name) {
508 DBG(" stdout package has no name !\n");
509 goto not_found;
510 }
511 spd = (u32 *)get_property(prom_stdout, "current-speed", NULL);
512 if (spd)
513 speed = *spd;
514
515 if (0)
516 ;
517#ifdef CONFIG_SERIAL_8250_CONSOLE
518 else if (strcmp(name, "serial") == 0) {
519 int i;
520 /* Look for it in probed array */
521 for (i = 0; i < legacy_serial_count; i++) {
522 if (prom_stdout != legacy_serial_infos[i].np)
523 continue;
524 offset = i;
525 speed = legacy_serial_infos[i].speed;
526 break;
527 }
528 if (i >= legacy_serial_count)
529 goto not_found;
530 }
531#endif /* CONFIG_SERIAL_8250_CONSOLE */
532#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
533 else if (strcmp(name, "ch-a") == 0)
534 offset = 0;
535 else if (strcmp(name, "ch-b") == 0)
536 offset = 1;
537#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
538 else
539 goto not_found;
540 of_node_put(prom_stdout);
541
542 DBG("Found serial console at ttyS%d\n", offset);
543
544 if (speed) {
545 static char __initdata opt[16];
546 sprintf(opt, "%d", speed);
547 return add_preferred_console("ttyS", offset, opt);
548 } else
549 return add_preferred_console("ttyS", offset, NULL);
550
551 not_found:
552 DBG("No preferred console found !\n");
553 of_node_put(prom_stdout);
554 return -ENODEV;
555}
556console_initcall(check_legacy_serial_console);
557
diff --git a/arch/powerpc/kernel/lparmap.c b/arch/powerpc/kernel/lparmap.c
index 5a05a797485f..584d1e3c013d 100644
--- a/arch/powerpc/kernel/lparmap.c
+++ b/arch/powerpc/kernel/lparmap.c
@@ -7,7 +7,7 @@
7 * 2 of the License, or (at your option) any later version. 7 * 2 of the License, or (at your option) any later version.
8 */ 8 */
9#include <asm/mmu.h> 9#include <asm/mmu.h>
10#include <asm/page.h> 10#include <asm/pgtable.h>
11#include <asm/iseries/lpar_map.h> 11#include <asm/iseries/lpar_map.h>
12 12
13const struct LparMap __attribute__((__section__(".text"))) xLparMap = { 13const struct LparMap __attribute__((__section__(".text"))) xLparMap = {
@@ -16,16 +16,16 @@ const struct LparMap __attribute__((__section__(".text"))) xLparMap = {
16 .xSegmentTableOffs = STAB0_PAGE, 16 .xSegmentTableOffs = STAB0_PAGE,
17 17
18 .xEsids = { 18 .xEsids = {
19 { .xKernelEsid = GET_ESID(KERNELBASE), 19 { .xKernelEsid = GET_ESID(PAGE_OFFSET),
20 .xKernelVsid = KERNEL_VSID(KERNELBASE), }, 20 .xKernelVsid = KERNEL_VSID(PAGE_OFFSET), },
21 { .xKernelEsid = GET_ESID(VMALLOCBASE), 21 { .xKernelEsid = GET_ESID(VMALLOC_START),
22 .xKernelVsid = KERNEL_VSID(VMALLOCBASE), }, 22 .xKernelVsid = KERNEL_VSID(VMALLOC_START), },
23 }, 23 },
24 24
25 .xRanges = { 25 .xRanges = {
26 { .xPages = HvPagesToMap, 26 { .xPages = HvPagesToMap,
27 .xOffset = 0, 27 .xOffset = 0,
28 .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - HW_PAGE_SHIFT), 28 .xVPN = KERNEL_VSID(PAGE_OFFSET) << (SID_SHIFT - HW_PAGE_SHIFT),
29 }, 29 },
30 }, 30 },
31}; 31};
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c
new file mode 100644
index 000000000000..a91e40c9ae45
--- /dev/null
+++ b/arch/powerpc/kernel/machine_kexec.c
@@ -0,0 +1,67 @@
1/*
2 * Code to handle transition of Linux booting another kernel.
3 *
4 * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com>
5 * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
6 * Copyright (C) 2005 IBM Corporation.
7 *
8 * This source code is licensed under the GNU General Public License,
9 * Version 2. See the file COPYING for more details.
10 */
11
12#include <linux/kexec.h>
13#include <linux/reboot.h>
14#include <linux/threads.h>
15#include <asm/machdep.h>
16
17/*
18 * Provide a dummy crash_notes definition until crash dump is implemented.
19 * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
20 */
21note_buf_t crash_notes[NR_CPUS];
22
23void machine_crash_shutdown(struct pt_regs *regs)
24{
25 if (ppc_md.machine_crash_shutdown)
26 ppc_md.machine_crash_shutdown(regs);
27}
28
29/*
30 * Do what every setup is needed on image and the
31 * reboot code buffer to allow us to avoid allocations
32 * later.
33 */
34int machine_kexec_prepare(struct kimage *image)
35{
36 if (ppc_md.machine_kexec_prepare)
37 return ppc_md.machine_kexec_prepare(image);
38 /*
39 * Fail if platform doesn't provide its own machine_kexec_prepare
40 * implementation.
41 */
42 return -ENOSYS;
43}
44
45void machine_kexec_cleanup(struct kimage *image)
46{
47 if (ppc_md.machine_kexec_cleanup)
48 ppc_md.machine_kexec_cleanup(image);
49}
50
51/*
52 * Do not allocate memory (or fail in any way) in machine_kexec().
53 * We are past the point of no return, committed to rebooting now.
54 */
55NORET_TYPE void machine_kexec(struct kimage *image)
56{
57 if (ppc_md.machine_kexec)
58 ppc_md.machine_kexec(image);
59 else {
60 /*
61 * Fall back to normal restart if platform doesn't provide
62 * its own kexec function, and user insist to kexec...
63 */
64 machine_restart(NULL);
65 }
66 for(;;);
67}
diff --git a/arch/powerpc/kernel/machine_kexec_32.c b/arch/powerpc/kernel/machine_kexec_32.c
new file mode 100644
index 000000000000..443606134dff
--- /dev/null
+++ b/arch/powerpc/kernel/machine_kexec_32.c
@@ -0,0 +1,65 @@
1/*
2 * PPC32 code to handle Linux booting another kernel.
3 *
4 * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com>
5 * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
6 * Copyright (C) 2005 IBM Corporation.
7 *
8 * This source code is licensed under the GNU General Public License,
9 * Version 2. See the file COPYING for more details.
10 */
11
12#include <linux/kexec.h>
13#include <linux/mm.h>
14#include <linux/string.h>
15#include <asm/cacheflush.h>
16#include <asm/hw_irq.h>
17#include <asm/io.h>
18
19typedef NORET_TYPE void (*relocate_new_kernel_t)(
20 unsigned long indirection_page,
21 unsigned long reboot_code_buffer,
22 unsigned long start_address) ATTRIB_NORET;
23
24/*
25 * This is a generic machine_kexec function suitable at least for
26 * non-OpenFirmware embedded platforms.
27 * It merely copies the image relocation code to the control page and
28 * jumps to it.
29 * A platform specific function may just call this one.
30 */
31void default_machine_kexec(struct kimage *image)
32{
33 const extern unsigned char relocate_new_kernel[];
34 const extern unsigned int relocate_new_kernel_size;
35 unsigned long page_list;
36 unsigned long reboot_code_buffer, reboot_code_buffer_phys;
37 relocate_new_kernel_t rnk;
38
39 /* Interrupts aren't acceptable while we reboot */
40 local_irq_disable();
41
42 page_list = image->head;
43
44 /* we need both effective and real address here */
45 reboot_code_buffer =
46 (unsigned long)page_address(image->control_code_page);
47 reboot_code_buffer_phys = virt_to_phys((void *)reboot_code_buffer);
48
49 /* copy our kernel relocation code to the control code page */
50 memcpy((void *)reboot_code_buffer, relocate_new_kernel,
51 relocate_new_kernel_size);
52
53 flush_icache_range(reboot_code_buffer,
54 reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE);
55 printk(KERN_INFO "Bye!\n");
56
57 /* now call it */
58 rnk = (relocate_new_kernel_t) reboot_code_buffer;
59 (*rnk)(page_list, reboot_code_buffer_phys, image->start);
60}
61
62int default_machine_kexec_prepare(struct kimage *image)
63{
64 return 0;
65}
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index 97c51e452be7..d6431440c54f 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * machine_kexec.c - handle transition of Linux booting another kernel 2 * PPC64 code to handle Linux booting another kernel.
3 * 3 *
4 * Copyright (C) 2004-2005, IBM Corp. 4 * Copyright (C) 2004-2005, IBM Corp.
5 * 5 *
@@ -28,21 +28,7 @@
28 28
29#define HASH_GROUP_SIZE 0x80 /* size of each hash group, asm/mmu.h */ 29#define HASH_GROUP_SIZE 0x80 /* size of each hash group, asm/mmu.h */
30 30
31/* Have this around till we move it into crash specific file */ 31int default_machine_kexec_prepare(struct kimage *image)
32note_buf_t crash_notes[NR_CPUS];
33
34/* Dummy for now. Not sure if we need to have a crash shutdown in here
35 * and if what it will achieve. Letting it be now to compile the code
36 * in generic kexec environment
37 */
38void machine_crash_shutdown(struct pt_regs *regs)
39{
40 /* do nothing right now */
41 /* smp_relase_cpus() if we want smp on panic kernel */
42 /* cpu_irq_down to isolate us until we are ready */
43}
44
45int machine_kexec_prepare(struct kimage *image)
46{ 32{
47 int i; 33 int i;
48 unsigned long begin, end; /* limits of segment */ 34 unsigned long begin, end; /* limits of segment */
@@ -111,11 +97,6 @@ int machine_kexec_prepare(struct kimage *image)
111 return 0; 97 return 0;
112} 98}
113 99
114void machine_kexec_cleanup(struct kimage *image)
115{
116 /* we do nothing in prepare that needs to be undone */
117}
118
119#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE) 100#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE)
120 101
121static void copy_segments(unsigned long ind) 102static void copy_segments(unsigned long ind)
@@ -172,9 +153,8 @@ void kexec_copy_flush(struct kimage *image)
172 * including ones that were in place on the original copy 153 * including ones that were in place on the original copy
173 */ 154 */
174 for (i = 0; i < nr_segments; i++) 155 for (i = 0; i < nr_segments; i++)
175 flush_icache_range(ranges[i].mem + KERNELBASE, 156 flush_icache_range((unsigned long)__va(ranges[i].mem),
176 ranges[i].mem + KERNELBASE + 157 (unsigned long)__va(ranges[i].mem + ranges[i].memsz));
177 ranges[i].memsz);
178} 158}
179 159
180#ifdef CONFIG_SMP 160#ifdef CONFIG_SMP
@@ -283,13 +263,20 @@ extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start,
283 void (*clear_all)(void)) ATTRIB_NORET; 263 void (*clear_all)(void)) ATTRIB_NORET;
284 264
285/* too late to fail here */ 265/* too late to fail here */
286void machine_kexec(struct kimage *image) 266void default_machine_kexec(struct kimage *image)
287{ 267{
288
289 /* prepare control code if any */ 268 /* prepare control code if any */
290 269
291 /* shutdown other cpus into our wait loop and quiesce interrupts */ 270 /*
292 kexec_prepare_cpus(); 271 * If the kexec boot is the normal one, need to shutdown other cpus
272 * into our wait loop and quiesce interrupts.
273 * Otherwise, in the case of crashed mode (crashing_cpu >= 0),
274 * stopping other CPUs and collecting their pt_regs is done before
275 * using debugger IPI.
276 */
277
278 if (crashing_cpu == -1)
279 kexec_prepare_cpus();
293 280
294 /* switch to a staticly allocated stack. Based on irq stack code. 281 /* switch to a staticly allocated stack. Based on irq stack code.
295 * XXX: the task struct will likely be invalid once we do the copy! 282 * XXX: the task struct will likely be invalid once we do the copy!
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 624a983a9676..01d0d97a16e1 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -5,6 +5,10 @@
5 * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) 5 * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
6 * and Paul Mackerras. 6 * and Paul Mackerras.
7 * 7 *
8 * kexec bits:
9 * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com>
10 * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
11 *
8 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 13 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 14 * as published by the Free Software Foundation; either version
@@ -24,6 +28,8 @@
24#include <asm/ppc_asm.h> 28#include <asm/ppc_asm.h>
25#include <asm/thread_info.h> 29#include <asm/thread_info.h>
26#include <asm/asm-offsets.h> 30#include <asm/asm-offsets.h>
31#include <asm/processor.h>
32#include <asm/kexec.h>
27 33
28 .text 34 .text
29 35
@@ -1006,3 +1012,110 @@ _GLOBAL(execve)
1006 */ 1012 */
1007_GLOBAL(__main) 1013_GLOBAL(__main)
1008 blr 1014 blr
1015
1016#ifdef CONFIG_KEXEC
1017 /*
1018 * Must be relocatable PIC code callable as a C function.
1019 */
1020 .globl relocate_new_kernel
1021relocate_new_kernel:
1022 /* r3 = page_list */
1023 /* r4 = reboot_code_buffer */
1024 /* r5 = start_address */
1025
1026 li r0, 0
1027
1028 /*
1029 * Set Machine Status Register to a known status,
1030 * switch the MMU off and jump to 1: in a single step.
1031 */
1032
1033 mr r8, r0
1034 ori r8, r8, MSR_RI|MSR_ME
1035 mtspr SPRN_SRR1, r8
1036 addi r8, r4, 1f - relocate_new_kernel
1037 mtspr SPRN_SRR0, r8
1038 sync
1039 rfi
1040
10411:
1042 /* from this point address translation is turned off */
1043 /* and interrupts are disabled */
1044
1045 /* set a new stack at the bottom of our page... */
1046 /* (not really needed now) */
1047 addi r1, r4, KEXEC_CONTROL_CODE_SIZE - 8 /* for LR Save+Back Chain */
1048 stw r0, 0(r1)
1049
1050 /* Do the copies */
1051 li r6, 0 /* checksum */
1052 mr r0, r3
1053 b 1f
1054
10550: /* top, read another word for the indirection page */
1056 lwzu r0, 4(r3)
1057
10581:
1059 /* is it a destination page? (r8) */
1060 rlwinm. r7, r0, 0, 31, 31 /* IND_DESTINATION (1<<0) */
1061 beq 2f
1062
1063 rlwinm r8, r0, 0, 0, 19 /* clear kexec flags, page align */
1064 b 0b
1065
10662: /* is it an indirection page? (r3) */
1067 rlwinm. r7, r0, 0, 30, 30 /* IND_INDIRECTION (1<<1) */
1068 beq 2f
1069
1070 rlwinm r3, r0, 0, 0, 19 /* clear kexec flags, page align */
1071 subi r3, r3, 4
1072 b 0b
1073
10742: /* are we done? */
1075 rlwinm. r7, r0, 0, 29, 29 /* IND_DONE (1<<2) */
1076 beq 2f
1077 b 3f
1078
10792: /* is it a source page? (r9) */
1080 rlwinm. r7, r0, 0, 28, 28 /* IND_SOURCE (1<<3) */
1081 beq 0b
1082
1083 rlwinm r9, r0, 0, 0, 19 /* clear kexec flags, page align */
1084
1085 li r7, PAGE_SIZE / 4
1086 mtctr r7
1087 subi r9, r9, 4
1088 subi r8, r8, 4
10899:
1090 lwzu r0, 4(r9) /* do the copy */
1091 xor r6, r6, r0
1092 stwu r0, 4(r8)
1093 dcbst 0, r8
1094 sync
1095 icbi 0, r8
1096 bdnz 9b
1097
1098 addi r9, r9, 4
1099 addi r8, r8, 4
1100 b 0b
1101
11023:
1103
1104 /* To be certain of avoiding problems with self-modifying code
1105 * execute a serializing instruction here.
1106 */
1107 isync
1108 sync
1109
1110 /* jump to the entry point, usually the setup routine */
1111 mtlr r5
1112 blrl
1113
11141: b 1b
1115
1116relocate_new_kernel_end:
1117
1118 .globl relocate_new_kernel_size
1119relocate_new_kernel_size:
1120 .long relocate_new_kernel_end - relocate_new_kernel
1121#endif
diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index c0fcd29918ce..fd7db8d542db 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -80,80 +80,74 @@ static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin)
80static ssize_t dev_nvram_read(struct file *file, char __user *buf, 80static ssize_t dev_nvram_read(struct file *file, char __user *buf,
81 size_t count, loff_t *ppos) 81 size_t count, loff_t *ppos)
82{ 82{
83 ssize_t len; 83 ssize_t ret;
84 char *tmp_buffer; 84 char *tmp = NULL;
85 int size; 85 ssize_t size;
86 86
87 if (ppc_md.nvram_size == NULL) 87 ret = -ENODEV;
88 return -ENODEV; 88 if (!ppc_md.nvram_size)
89 goto out;
90
91 ret = 0;
89 size = ppc_md.nvram_size(); 92 size = ppc_md.nvram_size();
93 if (*ppos >= size || size < 0)
94 goto out;
90 95
91 if (!access_ok(VERIFY_WRITE, buf, count)) 96 count = min_t(size_t, count, size - *ppos);
92 return -EFAULT; 97 count = min(count, PAGE_SIZE);
93 if (*ppos >= size)
94 return 0;
95 if (count > size)
96 count = size;
97 98
98 tmp_buffer = (char *) kmalloc(count, GFP_KERNEL); 99 ret = -ENOMEM;
99 if (!tmp_buffer) { 100 tmp = kmalloc(count, GFP_KERNEL);
100 printk(KERN_ERR "dev_read_nvram: kmalloc failed\n"); 101 if (!tmp)
101 return -ENOMEM; 102 goto out;
102 }
103 103
104 len = ppc_md.nvram_read(tmp_buffer, count, ppos); 104 ret = ppc_md.nvram_read(tmp, count, ppos);
105 if ((long)len <= 0) { 105 if (ret <= 0)
106 kfree(tmp_buffer); 106 goto out;
107 return len;
108 }
109 107
110 if (copy_to_user(buf, tmp_buffer, len)) { 108 if (copy_to_user(buf, tmp, ret))
111 kfree(tmp_buffer); 109 ret = -EFAULT;
112 return -EFAULT;
113 }
114 110
115 kfree(tmp_buffer); 111out:
116 return len; 112 kfree(tmp);
113 return ret;
117 114
118} 115}
119 116
120static ssize_t dev_nvram_write(struct file *file, const char __user *buf, 117static ssize_t dev_nvram_write(struct file *file, const char __user *buf,
121 size_t count, loff_t *ppos) 118 size_t count, loff_t *ppos)
122{ 119{
123 ssize_t len; 120 ssize_t ret;
124 char * tmp_buffer; 121 char *tmp = NULL;
125 int size; 122 ssize_t size;
126 123
127 if (ppc_md.nvram_size == NULL) 124 ret = -ENODEV;
128 return -ENODEV; 125 if (!ppc_md.nvram_size)
126 goto out;
127
128 ret = 0;
129 size = ppc_md.nvram_size(); 129 size = ppc_md.nvram_size();
130 if (*ppos >= size || size < 0)
131 goto out;
130 132
131 if (!access_ok(VERIFY_READ, buf, count)) 133 count = min_t(size_t, count, size - *ppos);
132 return -EFAULT; 134 count = min(count, PAGE_SIZE);
133 if (*ppos >= size)
134 return 0;
135 if (count > size)
136 count = size;
137 135
138 tmp_buffer = (char *) kmalloc(count, GFP_KERNEL); 136 ret = -ENOMEM;
139 if (!tmp_buffer) { 137 tmp = kmalloc(count, GFP_KERNEL);
140 printk(KERN_ERR "dev_nvram_write: kmalloc failed\n"); 138 if (!tmp)
141 return -ENOMEM; 139 goto out;
142 }
143
144 if (copy_from_user(tmp_buffer, buf, count)) {
145 kfree(tmp_buffer);
146 return -EFAULT;
147 }
148 140
149 len = ppc_md.nvram_write(tmp_buffer, count, ppos); 141 ret = -EFAULT;
150 if ((long)len <= 0) { 142 if (copy_from_user(tmp, buf, count))
151 kfree(tmp_buffer); 143 goto out;
152 return len; 144
153 } 145 ret = ppc_md.nvram_write(tmp, count, ppos);
146
147out:
148 kfree(tmp);
149 return ret;
154 150
155 kfree(tmp_buffer);
156 return len;
157} 151}
158 152
159static int dev_nvram_ioctl(struct inode *inode, struct file *file, 153static int dev_nvram_ioctl(struct inode *inode, struct file *file,
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index a7b68f911eb1..999bdd816769 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -17,6 +17,7 @@
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> 19#include <asm/iseries/it_lp_queue.h>
20#include <asm/iseries/it_lp_reg_save.h>
20#include <asm/paca.h> 21#include <asm/paca.h>
21 22
22 23
@@ -26,8 +27,7 @@ extern unsigned long __toc_start;
26 27
27/* The Paca is an array with one entry per processor. Each contains an 28/* The Paca is an array with one entry per processor. Each contains an
28 * lppaca, which contains the information shared between the 29 * lppaca, which contains the information shared between the
29 * hypervisor and Linux. Each also contains an ItLpRegSave area which 30 * hypervisor and Linux.
30 * is used by the hypervisor to save registers.
31 * On systems with hardware multi-threading, there are two threads 31 * On systems with hardware multi-threading, there are two threads
32 * per processor. The Paca array must contain an entry for each thread. 32 * per processor. The Paca array must contain an entry for each thread.
33 * The VPD Areas will give a max logical processors = 2 * max physical 33 * The VPD Areas will give a max logical processors = 2 * max physical
@@ -37,7 +37,6 @@ extern unsigned long __toc_start;
37#define PACA_INIT_COMMON(number, start, asrr, asrv) \ 37#define PACA_INIT_COMMON(number, start, asrr, asrv) \
38 .lock_token = 0x8000, \ 38 .lock_token = 0x8000, \
39 .paca_index = (number), /* Paca Index */ \ 39 .paca_index = (number), /* Paca Index */ \
40 .default_decr = 0x00ff0000, /* Initial Decr */ \
41 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ 40 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \
42 .stab_real = (asrr), /* Real pointer to segment table */ \ 41 .stab_real = (asrr), /* Real pointer to segment table */ \
43 .stab_addr = (asrv), /* Virt pointer to segment table */ \ 42 .stab_addr = (asrv), /* Virt pointer to segment table */ \
@@ -57,11 +56,7 @@ extern unsigned long __toc_start;
57#ifdef CONFIG_PPC_ISERIES 56#ifdef CONFIG_PPC_ISERIES
58#define PACA_INIT_ISERIES(number) \ 57#define PACA_INIT_ISERIES(number) \
59 .lppaca_ptr = &paca[number].lppaca, \ 58 .lppaca_ptr = &paca[number].lppaca, \
60 .reg_save_ptr = &paca[number].reg_save, \ 59 .reg_save_ptr = &iseries_reg_save[number],
61 .reg_save = { \
62 .xDesc = 0xd397d9e2, /* "LpRS" */ \
63 .xSize = sizeof(struct ItLpRegSave) \
64 }
65 60
66#define PACA_INIT(number) \ 61#define PACA_INIT(number) \
67{ \ 62{ \
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 8b6008ab217d..fc60a773af7d 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -34,7 +34,7 @@
34 34
35#ifdef DEBUG 35#ifdef DEBUG
36#include <asm/udbg.h> 36#include <asm/udbg.h>
37#define DBG(fmt...) udbg_printf(fmt) 37#define DBG(fmt...) printk(fmt)
38#else 38#else
39#define DBG(fmt...) 39#define DBG(fmt...)
40#endif 40#endif
@@ -251,7 +251,7 @@ void pcibios_free_controller(struct pci_controller *phb)
251 kfree(phb); 251 kfree(phb);
252} 252}
253 253
254static void __init pcibios_claim_one_bus(struct pci_bus *b) 254void __devinit pcibios_claim_one_bus(struct pci_bus *b)
255{ 255{
256 struct pci_dev *dev; 256 struct pci_dev *dev;
257 struct pci_bus *child_bus; 257 struct pci_bus *child_bus;
@@ -323,6 +323,7 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
323 addrs = (u32 *) get_property(node, "assigned-addresses", &proplen); 323 addrs = (u32 *) get_property(node, "assigned-addresses", &proplen);
324 if (!addrs) 324 if (!addrs)
325 return; 325 return;
326 DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs);
326 for (; proplen >= 20; proplen -= 20, addrs += 5) { 327 for (; proplen >= 20; proplen -= 20, addrs += 5) {
327 flags = pci_parse_of_flags(addrs[0]); 328 flags = pci_parse_of_flags(addrs[0]);
328 if (!flags) 329 if (!flags)
@@ -332,6 +333,9 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
332 if (!size) 333 if (!size)
333 continue; 334 continue;
334 i = addrs[0] & 0xff; 335 i = addrs[0] & 0xff;
336 DBG(" base: %llx, size: %llx, i: %x\n",
337 (unsigned long long)base, (unsigned long long)size, i);
338
335 if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) { 339 if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
336 res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; 340 res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
337 } else if (i == dev->rom_base_reg) { 341 } else if (i == dev->rom_base_reg) {
@@ -362,6 +366,8 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
362 if (type == NULL) 366 if (type == NULL)
363 type = ""; 367 type = "";
364 368
369 DBG(" create device, devfn: %x, type: %s\n", devfn, type);
370
365 memset(dev, 0, sizeof(struct pci_dev)); 371 memset(dev, 0, sizeof(struct pci_dev));
366 dev->bus = bus; 372 dev->bus = bus;
367 dev->sysdata = node; 373 dev->sysdata = node;
@@ -381,6 +387,8 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
381 dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); 387 dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
382 dev->class = get_int_prop(node, "class-code", 0); 388 dev->class = get_int_prop(node, "class-code", 0);
383 389
390 DBG(" class: 0x%x\n", dev->class);
391
384 dev->current_state = 4; /* unknown power state */ 392 dev->current_state = 4; /* unknown power state */
385 393
386 if (!strcmp(type, "pci")) { 394 if (!strcmp(type, "pci")) {
@@ -402,6 +410,8 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
402 410
403 pci_parse_of_addrs(node, dev); 411 pci_parse_of_addrs(node, dev);
404 412
413 DBG(" adding to system ...\n");
414
405 pci_device_add(dev, bus); 415 pci_device_add(dev, bus);
406 416
407 /* XXX pci_scan_msi_device(dev); */ 417 /* XXX pci_scan_msi_device(dev); */
@@ -418,15 +428,21 @@ void __devinit of_scan_bus(struct device_node *node,
418 int reglen, devfn; 428 int reglen, devfn;
419 struct pci_dev *dev; 429 struct pci_dev *dev;
420 430
431 DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number);
432
421 while ((child = of_get_next_child(node, child)) != NULL) { 433 while ((child = of_get_next_child(node, child)) != NULL) {
434 DBG(" * %s\n", child->full_name);
422 reg = (u32 *) get_property(child, "reg", &reglen); 435 reg = (u32 *) get_property(child, "reg", &reglen);
423 if (reg == NULL || reglen < 20) 436 if (reg == NULL || reglen < 20)
424 continue; 437 continue;
425 devfn = (reg[0] >> 8) & 0xff; 438 devfn = (reg[0] >> 8) & 0xff;
439
426 /* create a new pci_dev for this device */ 440 /* create a new pci_dev for this device */
427 dev = of_create_pci_dev(child, bus, devfn); 441 dev = of_create_pci_dev(child, bus, devfn);
428 if (!dev) 442 if (!dev)
429 continue; 443 continue;
444 DBG("dev header type: %x\n", dev->hdr_type);
445
430 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || 446 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
431 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) 447 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
432 of_scan_pci_bridge(child, dev); 448 of_scan_pci_bridge(child, dev);
@@ -446,16 +462,18 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
446 unsigned int flags; 462 unsigned int flags;
447 u64 size; 463 u64 size;
448 464
465 DBG("of_scan_pci_bridge(%s)\n", node->full_name);
466
449 /* parse bus-range property */ 467 /* parse bus-range property */
450 busrange = (u32 *) get_property(node, "bus-range", &len); 468 busrange = (u32 *) get_property(node, "bus-range", &len);
451 if (busrange == NULL || len != 8) { 469 if (busrange == NULL || len != 8) {
452 printk(KERN_ERR "Can't get bus-range for PCI-PCI bridge %s\n", 470 printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n",
453 node->full_name); 471 node->full_name);
454 return; 472 return;
455 } 473 }
456 ranges = (u32 *) get_property(node, "ranges", &len); 474 ranges = (u32 *) get_property(node, "ranges", &len);
457 if (ranges == NULL) { 475 if (ranges == NULL) {
458 printk(KERN_ERR "Can't get ranges for PCI-PCI bridge %s\n", 476 printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
459 node->full_name); 477 node->full_name);
460 return; 478 return;
461 } 479 }
@@ -509,10 +527,13 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
509 } 527 }
510 sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), 528 sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
511 bus->number); 529 bus->number);
530 DBG(" bus name: %s\n", bus->name);
512 531
513 mode = PCI_PROBE_NORMAL; 532 mode = PCI_PROBE_NORMAL;
514 if (ppc_md.pci_probe_mode) 533 if (ppc_md.pci_probe_mode)
515 mode = ppc_md.pci_probe_mode(bus); 534 mode = ppc_md.pci_probe_mode(bus);
535 DBG(" probe mode: %d\n", mode);
536
516 if (mode == PCI_PROBE_DEVTREE) 537 if (mode == PCI_PROBE_DEVTREE)
517 of_scan_bus(node, bus); 538 of_scan_bus(node, bus);
518 else if (mode == PCI_PROBE_NORMAL) 539 else if (mode == PCI_PROBE_NORMAL)
@@ -528,6 +549,8 @@ void __devinit scan_phb(struct pci_controller *hose)
528 int i, mode; 549 int i, mode;
529 struct resource *res; 550 struct resource *res;
530 551
552 DBG("Scanning PHB %s\n", node ? node->full_name : "<NO NAME>");
553
531 bus = pci_create_bus(NULL, hose->first_busno, hose->ops, node); 554 bus = pci_create_bus(NULL, hose->first_busno, hose->ops, node);
532 if (bus == NULL) { 555 if (bus == NULL) {
533 printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", 556 printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
@@ -552,8 +575,9 @@ void __devinit scan_phb(struct pci_controller *hose)
552 575
553 mode = PCI_PROBE_NORMAL; 576 mode = PCI_PROBE_NORMAL;
554#ifdef CONFIG_PPC_MULTIPLATFORM 577#ifdef CONFIG_PPC_MULTIPLATFORM
555 if (ppc_md.pci_probe_mode) 578 if (node && ppc_md.pci_probe_mode)
556 mode = ppc_md.pci_probe_mode(bus); 579 mode = ppc_md.pci_probe_mode(bus);
580 DBG(" probe mode: %d\n", mode);
557 if (mode == PCI_PROBE_DEVTREE) { 581 if (mode == PCI_PROBE_DEVTREE) {
558 bus->subordinate = hose->last_busno; 582 bus->subordinate = hose->last_busno;
559 of_scan_bus(node, bus); 583 of_scan_bus(node, bus);
@@ -842,8 +866,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file,
842 * Returns a negative error code on failure, zero on success. 866 * Returns a negative error code on failure, zero on success.
843 */ 867 */
844int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, 868int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
845 enum pci_mmap_state mmap_state, 869 enum pci_mmap_state mmap_state, int write_combine)
846 int write_combine)
847{ 870{
848 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; 871 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
849 struct resource *rp; 872 struct resource *rp;
@@ -896,6 +919,25 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
896 unsigned long phb_io_base_phys, 919 unsigned long phb_io_base_phys,
897 void __iomem * phb_io_base_virt) 920 void __iomem * phb_io_base_virt)
898{ 921{
922 /* Remove these asap */
923
924 struct pci_address {
925 u32 a_hi;
926 u32 a_mid;
927 u32 a_lo;
928 };
929
930 struct isa_address {
931 u32 a_hi;
932 u32 a_lo;
933 };
934
935 struct isa_range {
936 struct isa_address isa_addr;
937 struct pci_address pci_addr;
938 unsigned int size;
939 };
940
899 struct isa_range *range; 941 struct isa_range *range;
900 unsigned long pci_addr; 942 unsigned long pci_addr;
901 unsigned int isa_addr; 943 unsigned int isa_addr;
@@ -1223,6 +1265,7 @@ void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
1223} 1265}
1224EXPORT_SYMBOL(pcibios_fixup_device_resources); 1266EXPORT_SYMBOL(pcibios_fixup_device_resources);
1225 1267
1268
1226static void __devinit do_bus_setup(struct pci_bus *bus) 1269static void __devinit do_bus_setup(struct pci_bus *bus)
1227{ 1270{
1228 struct pci_dev *dev; 1271 struct pci_dev *dev;
@@ -1306,8 +1349,38 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
1306 *end = rsrc->end + offset; 1349 *end = rsrc->end + offset;
1307} 1350}
1308 1351
1352struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
1353{
1354 if (!have_of)
1355 return NULL;
1356 while(node) {
1357 struct pci_controller *hose, *tmp;
1358 list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
1359 if (hose->arch_data == node)
1360 return hose;
1361 node = node->parent;
1362 }
1363 return NULL;
1364}
1365
1309#endif /* CONFIG_PPC_MULTIPLATFORM */ 1366#endif /* CONFIG_PPC_MULTIPLATFORM */
1310 1367
1368unsigned long pci_address_to_pio(phys_addr_t address)
1369{
1370 struct pci_controller *hose, *tmp;
1371
1372 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
1373 if (address >= hose->io_base_phys &&
1374 address < (hose->io_base_phys + hose->pci_io_size)) {
1375 unsigned long base =
1376 (unsigned long)hose->io_base_virt - pci_io_base;
1377 return base + (address - hose->io_base_phys);
1378 }
1379 }
1380 return (unsigned int)-1;
1381}
1382EXPORT_SYMBOL_GPL(pci_address_to_pio);
1383
1311 1384
1312#define IOBASE_BRIDGE_NUMBER 0 1385#define IOBASE_BRIDGE_NUMBER 0
1313#define IOBASE_MEMORY 1 1386#define IOBASE_MEMORY 1
diff --git a/arch/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c
index 2d333cc84082..e6fb194fe537 100644
--- a/arch/powerpc/kernel/pmc.c
+++ b/arch/powerpc/kernel/pmc.c
@@ -43,8 +43,13 @@ static void dummy_perf(struct pt_regs *regs)
43 mtspr(SPRN_MMCR0, mmcr0); 43 mtspr(SPRN_MMCR0, mmcr0);
44} 44}
45#else 45#else
46/* Ensure exceptions are disabled */
46static void dummy_perf(struct pt_regs *regs) 47static void dummy_perf(struct pt_regs *regs)
47{ 48{
49 unsigned int mmcr0 = mfspr(SPRN_MMCR0);
50
51 mmcr0 &= ~(MMCR0_PMXE);
52 mtspr(SPRN_MMCR0, mmcr0);
48} 53}
49#endif 54#endif
50 55
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 94db25708456..b2758148a0de 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -76,11 +76,6 @@ EXPORT_SYMBOL(single_step_exception);
76EXPORT_SYMBOL(sys_sigreturn); 76EXPORT_SYMBOL(sys_sigreturn);
77#endif 77#endif
78 78
79#if defined(CONFIG_PPC_PREP)
80EXPORT_SYMBOL(_prep_type);
81EXPORT_SYMBOL(ucSystemType);
82#endif
83
84EXPORT_SYMBOL(strcpy); 79EXPORT_SYMBOL(strcpy);
85EXPORT_SYMBOL(strncpy); 80EXPORT_SYMBOL(strncpy);
86EXPORT_SYMBOL(strcat); 81EXPORT_SYMBOL(strcat);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 3bf968e74095..977ee3adaf2d 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -29,6 +29,7 @@
29#include <linux/initrd.h> 29#include <linux/initrd.h>
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 33
33#include <asm/prom.h> 34#include <asm/prom.h>
34#include <asm/rtas.h> 35#include <asm/rtas.h>
@@ -37,6 +38,7 @@
37#include <asm/processor.h> 38#include <asm/processor.h>
38#include <asm/irq.h> 39#include <asm/irq.h>
39#include <asm/io.h> 40#include <asm/io.h>
41#include <asm/kdump.h>
40#include <asm/smp.h> 42#include <asm/smp.h>
41#include <asm/system.h> 43#include <asm/system.h>
42#include <asm/mmu.h> 44#include <asm/mmu.h>
@@ -55,21 +57,6 @@
55#define DBG(fmt...) 57#define DBG(fmt...)
56#endif 58#endif
57 59
58struct pci_reg_property {
59 struct pci_address addr;
60 u32 size_hi;
61 u32 size_lo;
62};
63
64struct isa_reg_property {
65 u32 space;
66 u32 address;
67 u32 size;
68};
69
70
71typedef int interpret_func(struct device_node *, unsigned long *,
72 int, int, int);
73 60
74static int __initdata dt_root_addr_cells; 61static int __initdata dt_root_addr_cells;
75static int __initdata dt_root_size_cells; 62static int __initdata dt_root_size_cells;
@@ -311,6 +298,16 @@ static int __devinit finish_node_interrupts(struct device_node *np,
311 int i, j, n, sense; 298 int i, j, n, sense;
312 unsigned int *irq, virq; 299 unsigned int *irq, virq;
313 struct device_node *ic; 300 struct device_node *ic;
301 int trace = 0;
302
303 //#define TRACE(fmt...) do { if (trace) { printk(fmt); mdelay(1000); } } while(0)
304#define TRACE(fmt...)
305
306 if (!strcmp(np->name, "smu-doorbell"))
307 trace = 1;
308
309 TRACE("Finishing SMU doorbell ! num_interrupt_controllers = %d\n",
310 num_interrupt_controllers);
314 311
315 if (num_interrupt_controllers == 0) { 312 if (num_interrupt_controllers == 0) {
316 /* 313 /*
@@ -345,11 +342,12 @@ static int __devinit finish_node_interrupts(struct device_node *np,
345 } 342 }
346 343
347 ints = (unsigned int *) get_property(np, "interrupts", &intlen); 344 ints = (unsigned int *) get_property(np, "interrupts", &intlen);
345 TRACE("ints=%p, intlen=%d\n", ints, intlen);
348 if (ints == NULL) 346 if (ints == NULL)
349 return 0; 347 return 0;
350 intrcells = prom_n_intr_cells(np); 348 intrcells = prom_n_intr_cells(np);
351 intlen /= intrcells * sizeof(unsigned int); 349 intlen /= intrcells * sizeof(unsigned int);
352 350 TRACE("intrcells=%d, new intlen=%d\n", intrcells, intlen);
353 np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start); 351 np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start);
354 if (!np->intrs) 352 if (!np->intrs)
355 return -ENOMEM; 353 return -ENOMEM;
@@ -360,6 +358,7 @@ static int __devinit finish_node_interrupts(struct device_node *np,
360 intrcount = 0; 358 intrcount = 0;
361 for (i = 0; i < intlen; ++i, ints += intrcells) { 359 for (i = 0; i < intlen; ++i, ints += intrcells) {
362 n = map_interrupt(&irq, &ic, np, ints, intrcells); 360 n = map_interrupt(&irq, &ic, np, ints, intrcells);
361 TRACE("map, irq=%d, ic=%p, n=%d\n", irq, ic, n);
363 if (n <= 0) 362 if (n <= 0)
364 continue; 363 continue;
365 364
@@ -370,6 +369,7 @@ static int __devinit finish_node_interrupts(struct device_node *np,
370 np->intrs[intrcount].sense = map_isa_senses[sense]; 369 np->intrs[intrcount].sense = map_isa_senses[sense];
371 } else { 370 } else {
372 virq = virt_irq_create_mapping(irq[0]); 371 virq = virt_irq_create_mapping(irq[0]);
372 TRACE("virq=%d\n", virq);
373#ifdef CONFIG_PPC64 373#ifdef CONFIG_PPC64
374 if (virq == NO_IRQ) { 374 if (virq == NO_IRQ) {
375 printk(KERN_CRIT "Could not allocate interrupt" 375 printk(KERN_CRIT "Could not allocate interrupt"
@@ -379,6 +379,12 @@ static int __devinit finish_node_interrupts(struct device_node *np,
379#endif 379#endif
380 np->intrs[intrcount].line = irq_offset_up(virq); 380 np->intrs[intrcount].line = irq_offset_up(virq);
381 sense = (n > 1)? (irq[1] & 3): 1; 381 sense = (n > 1)? (irq[1] & 3): 1;
382
383 /* Apple uses bits in there in a different way, let's
384 * only keep the real sense bit on macs
385 */
386 if (_machine == PLATFORM_POWERMAC)
387 sense &= 0x1;
382 np->intrs[intrcount].sense = map_mpic_senses[sense]; 388 np->intrs[intrcount].sense = map_mpic_senses[sense];
383 } 389 }
384 390
@@ -388,12 +394,13 @@ static int __devinit finish_node_interrupts(struct device_node *np,
388 char *name = get_property(ic->parent, "name", NULL); 394 char *name = get_property(ic->parent, "name", NULL);
389 if (name && !strcmp(name, "u3")) 395 if (name && !strcmp(name, "u3"))
390 np->intrs[intrcount].line += 128; 396 np->intrs[intrcount].line += 128;
391 else if (!(name && !strcmp(name, "mac-io"))) 397 else if (!(name && (!strcmp(name, "mac-io") ||
398 !strcmp(name, "u4"))))
392 /* ignore other cascaded controllers, such as 399 /* ignore other cascaded controllers, such as
393 the k2-sata-root */ 400 the k2-sata-root */
394 break; 401 break;
395 } 402 }
396#endif 403#endif /* CONFIG_PPC64 */
397 if (n > 2) { 404 if (n > 2) {
398 printk("hmmm, got %d intr cells for %s:", n, 405 printk("hmmm, got %d intr cells for %s:", n,
399 np->full_name); 406 np->full_name);
@@ -408,234 +415,19 @@ static int __devinit finish_node_interrupts(struct device_node *np,
408 return 0; 415 return 0;
409} 416}
410 417
411static int __devinit interpret_pci_props(struct device_node *np,
412 unsigned long *mem_start,
413 int naddrc, int nsizec,
414 int measure_only)
415{
416 struct address_range *adr;
417 struct pci_reg_property *pci_addrs;
418 int i, l, n_addrs;
419
420 pci_addrs = (struct pci_reg_property *)
421 get_property(np, "assigned-addresses", &l);
422 if (!pci_addrs)
423 return 0;
424
425 n_addrs = l / sizeof(*pci_addrs);
426
427 adr = prom_alloc(n_addrs * sizeof(*adr), mem_start);
428 if (!adr)
429 return -ENOMEM;
430
431 if (measure_only)
432 return 0;
433
434 np->addrs = adr;
435 np->n_addrs = n_addrs;
436
437 for (i = 0; i < n_addrs; i++) {
438 adr[i].space = pci_addrs[i].addr.a_hi;
439 adr[i].address = pci_addrs[i].addr.a_lo |
440 ((u64)pci_addrs[i].addr.a_mid << 32);
441 adr[i].size = pci_addrs[i].size_lo;
442 }
443
444 return 0;
445}
446
447static int __init interpret_dbdma_props(struct device_node *np,
448 unsigned long *mem_start,
449 int naddrc, int nsizec,
450 int measure_only)
451{
452 struct reg_property32 *rp;
453 struct address_range *adr;
454 unsigned long base_address;
455 int i, l;
456 struct device_node *db;
457
458 base_address = 0;
459 if (!measure_only) {
460 for (db = np->parent; db != NULL; db = db->parent) {
461 if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
462 base_address = db->addrs[0].address;
463 break;
464 }
465 }
466 }
467
468 rp = (struct reg_property32 *) get_property(np, "reg", &l);
469 if (rp != 0 && l >= sizeof(struct reg_property32)) {
470 i = 0;
471 adr = (struct address_range *) (*mem_start);
472 while ((l -= sizeof(struct reg_property32)) >= 0) {
473 if (!measure_only) {
474 adr[i].space = 2;
475 adr[i].address = rp[i].address + base_address;
476 adr[i].size = rp[i].size;
477 }
478 ++i;
479 }
480 np->addrs = adr;
481 np->n_addrs = i;
482 (*mem_start) += i * sizeof(struct address_range);
483 }
484
485 return 0;
486}
487
488static int __init interpret_macio_props(struct device_node *np,
489 unsigned long *mem_start,
490 int naddrc, int nsizec,
491 int measure_only)
492{
493 struct reg_property32 *rp;
494 struct address_range *adr;
495 unsigned long base_address;
496 int i, l;
497 struct device_node *db;
498
499 base_address = 0;
500 if (!measure_only) {
501 for (db = np->parent; db != NULL; db = db->parent) {
502 if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
503 base_address = db->addrs[0].address;
504 break;
505 }
506 }
507 }
508
509 rp = (struct reg_property32 *) get_property(np, "reg", &l);
510 if (rp != 0 && l >= sizeof(struct reg_property32)) {
511 i = 0;
512 adr = (struct address_range *) (*mem_start);
513 while ((l -= sizeof(struct reg_property32)) >= 0) {
514 if (!measure_only) {
515 adr[i].space = 2;
516 adr[i].address = rp[i].address + base_address;
517 adr[i].size = rp[i].size;
518 }
519 ++i;
520 }
521 np->addrs = adr;
522 np->n_addrs = i;
523 (*mem_start) += i * sizeof(struct address_range);
524 }
525
526 return 0;
527}
528
529static int __init interpret_isa_props(struct device_node *np,
530 unsigned long *mem_start,
531 int naddrc, int nsizec,
532 int measure_only)
533{
534 struct isa_reg_property *rp;
535 struct address_range *adr;
536 int i, l;
537
538 rp = (struct isa_reg_property *) get_property(np, "reg", &l);
539 if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
540 i = 0;
541 adr = (struct address_range *) (*mem_start);
542 while ((l -= sizeof(struct isa_reg_property)) >= 0) {
543 if (!measure_only) {
544 adr[i].space = rp[i].space;
545 adr[i].address = rp[i].address;
546 adr[i].size = rp[i].size;
547 }
548 ++i;
549 }
550 np->addrs = adr;
551 np->n_addrs = i;
552 (*mem_start) += i * sizeof(struct address_range);
553 }
554
555 return 0;
556}
557
558static int __init interpret_root_props(struct device_node *np,
559 unsigned long *mem_start,
560 int naddrc, int nsizec,
561 int measure_only)
562{
563 struct address_range *adr;
564 int i, l;
565 unsigned int *rp;
566 int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
567
568 rp = (unsigned int *) get_property(np, "reg", &l);
569 if (rp != 0 && l >= rpsize) {
570 i = 0;
571 adr = (struct address_range *) (*mem_start);
572 while ((l -= rpsize) >= 0) {
573 if (!measure_only) {
574 adr[i].space = 0;
575 adr[i].address = rp[naddrc - 1];
576 adr[i].size = rp[naddrc + nsizec - 1];
577 }
578 ++i;
579 rp += naddrc + nsizec;
580 }
581 np->addrs = adr;
582 np->n_addrs = i;
583 (*mem_start) += i * sizeof(struct address_range);
584 }
585
586 return 0;
587}
588
589static int __devinit finish_node(struct device_node *np, 418static int __devinit finish_node(struct device_node *np,
590 unsigned long *mem_start, 419 unsigned long *mem_start,
591 interpret_func *ifunc,
592 int naddrc, int nsizec,
593 int measure_only) 420 int measure_only)
594{ 421{
595 struct device_node *child; 422 struct device_node *child;
596 int *ip, rc = 0; 423 int rc = 0;
597
598 /* get the device addresses and interrupts */
599 if (ifunc != NULL)
600 rc = ifunc(np, mem_start, naddrc, nsizec, measure_only);
601 if (rc)
602 goto out;
603 424
604 rc = finish_node_interrupts(np, mem_start, measure_only); 425 rc = finish_node_interrupts(np, mem_start, measure_only);
605 if (rc) 426 if (rc)
606 goto out; 427 goto out;
607 428
608 /* Look for #address-cells and #size-cells properties. */
609 ip = (int *) get_property(np, "#address-cells", NULL);
610 if (ip != NULL)
611 naddrc = *ip;
612 ip = (int *) get_property(np, "#size-cells", NULL);
613 if (ip != NULL)
614 nsizec = *ip;
615
616 if (!strcmp(np->name, "device-tree") || np->parent == NULL)
617 ifunc = interpret_root_props;
618 else if (np->type == 0)
619 ifunc = NULL;
620 else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
621 ifunc = interpret_pci_props;
622 else if (!strcmp(np->type, "dbdma"))
623 ifunc = interpret_dbdma_props;
624 else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props)
625 ifunc = interpret_macio_props;
626 else if (!strcmp(np->type, "isa"))
627 ifunc = interpret_isa_props;
628 else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
629 ifunc = interpret_root_props;
630 else if (!((ifunc == interpret_dbdma_props
631 || ifunc == interpret_macio_props)
632 && (!strcmp(np->type, "escc")
633 || !strcmp(np->type, "media-bay"))))
634 ifunc = NULL;
635
636 for (child = np->child; child != NULL; child = child->sibling) { 429 for (child = np->child; child != NULL; child = child->sibling) {
637 rc = finish_node(child, mem_start, ifunc, 430 rc = finish_node(child, mem_start, measure_only);
638 naddrc, nsizec, measure_only);
639 if (rc) 431 if (rc)
640 goto out; 432 goto out;
641 } 433 }
@@ -697,10 +489,10 @@ void __init finish_device_tree(void)
697 * reason and then remove those additional 16 bytes 489 * reason and then remove those additional 16 bytes
698 */ 490 */
699 size = 16; 491 size = 16;
700 finish_node(allnodes, &size, NULL, 0, 0, 1); 492 finish_node(allnodes, &size, 1);
701 size -= 16; 493 size -= 16;
702 end = start = (unsigned long) __va(lmb_alloc(size, 128)); 494 end = start = (unsigned long) __va(lmb_alloc(size, 128));
703 finish_node(allnodes, &end, NULL, 0, 0, 0); 495 finish_node(allnodes, &end, 0);
704 BUG_ON(end != start + size); 496 BUG_ON(end != start + size);
705 497
706 DBG(" <- finish_device_tree\n"); 498 DBG(" <- finish_device_tree\n");
@@ -1197,6 +989,16 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
1197 } 989 }
1198#endif /* CONFIG_PPC_RTAS */ 990#endif /* CONFIG_PPC_RTAS */
1199 991
992#ifdef CONFIG_KEXEC
993 lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL);
994 if (lprop)
995 crashk_res.start = *lprop;
996
997 lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-size", NULL);
998 if (lprop)
999 crashk_res.end = crashk_res.start + *lprop - 1;
1000#endif
1001
1200 /* break now */ 1002 /* break now */
1201 return 1; 1003 return 1;
1202} 1004}
@@ -1263,7 +1065,9 @@ static int __init early_init_dt_scan_memory(unsigned long node,
1263 } else if (strcmp(type, "memory") != 0) 1065 } else if (strcmp(type, "memory") != 0)
1264 return 0; 1066 return 0;
1265 1067
1266 reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l); 1068 reg = (cell_t *)of_get_flat_dt_prop(node, "linux,usable-memory", &l);
1069 if (reg == NULL)
1070 reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
1267 if (reg == NULL) 1071 if (reg == NULL)
1268 return 0; 1072 return 0;
1269 1073
@@ -1335,11 +1139,14 @@ void __init early_init_devtree(void *params)
1335 of_scan_flat_dt(early_init_dt_scan_memory, NULL); 1139 of_scan_flat_dt(early_init_dt_scan_memory, NULL);
1336 lmb_enforce_memory_limit(memory_limit); 1140 lmb_enforce_memory_limit(memory_limit);
1337 lmb_analyze(); 1141 lmb_analyze();
1338 lmb_reserve(0, __pa(klimit));
1339 1142
1340 DBG("Phys. mem: %lx\n", lmb_phys_mem_size()); 1143 DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
1341 1144
1342 /* Reserve LMB regions used by kernel, initrd, dt, etc... */ 1145 /* Reserve LMB regions used by kernel, initrd, dt, etc... */
1146 lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
1147#ifdef CONFIG_CRASH_DUMP
1148 lmb_reserve(0, KDUMP_RESERVE_LIMIT);
1149#endif
1343 early_reserve_mem(); 1150 early_reserve_mem();
1344 1151
1345 DBG("Scanning CPUs ...\n"); 1152 DBG("Scanning CPUs ...\n");
@@ -1802,7 +1609,6 @@ static void of_node_release(struct kref *kref)
1802 prop = next; 1609 prop = next;
1803 } 1610 }
1804 kfree(node->intrs); 1611 kfree(node->intrs);
1805 kfree(node->addrs);
1806 kfree(node->full_name); 1612 kfree(node->full_name);
1807 kfree(node->data); 1613 kfree(node->data);
1808 kfree(node); 1614 kfree(node);
@@ -1884,9 +1690,7 @@ void of_detach_node(const struct device_node *np)
1884 * This should probably be split up into smaller chunks. 1690 * This should probably be split up into smaller chunks.
1885 */ 1691 */
1886 1692
1887static int of_finish_dynamic_node(struct device_node *node, 1693static int of_finish_dynamic_node(struct device_node *node)
1888 unsigned long *unused1, int unused2,
1889 int unused3, int unused4)
1890{ 1694{
1891 struct device_node *parent = of_get_parent(node); 1695 struct device_node *parent = of_get_parent(node);
1892 int err = 0; 1696 int err = 0;
@@ -1907,7 +1711,8 @@ static int of_finish_dynamic_node(struct device_node *node,
1907 return -ENODEV; 1711 return -ENODEV;
1908 1712
1909 /* fix up new node's linux_phandle field */ 1713 /* fix up new node's linux_phandle field */
1910 if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL))) 1714 if ((ibm_phandle = (unsigned int *)get_property(node,
1715 "ibm,phandle", NULL)))
1911 node->linux_phandle = *ibm_phandle; 1716 node->linux_phandle = *ibm_phandle;
1912 1717
1913out: 1718out:
@@ -1922,7 +1727,9 @@ static int prom_reconfig_notifier(struct notifier_block *nb,
1922 1727
1923 switch (action) { 1728 switch (action) {
1924 case PSERIES_RECONFIG_ADD: 1729 case PSERIES_RECONFIG_ADD:
1925 err = finish_node(node, NULL, of_finish_dynamic_node, 0, 0, 0); 1730 err = of_finish_dynamic_node(node);
1731 if (!err)
1732 finish_node(node, NULL, 0);
1926 if (err < 0) { 1733 if (err < 0) {
1927 printk(KERN_ERR "finish_node returned %d\n", err); 1734 printk(KERN_ERR "finish_node returned %d\n", err);
1928 err = NOTIFY_BAD; 1735 err = NOTIFY_BAD;
@@ -1996,175 +1803,4 @@ int prom_add_property(struct device_node* np, struct property* prop)
1996 return 0; 1803 return 0;
1997} 1804}
1998 1805
1999/* I quickly hacked that one, check against spec ! */
2000static inline unsigned long
2001bus_space_to_resource_flags(unsigned int bus_space)
2002{
2003 u8 space = (bus_space >> 24) & 0xf;
2004 if (space == 0)
2005 space = 0x02;
2006 if (space == 0x02)
2007 return IORESOURCE_MEM;
2008 else if (space == 0x01)
2009 return IORESOURCE_IO;
2010 else {
2011 printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n",
2012 bus_space);
2013 return 0;
2014 }
2015}
2016
2017#ifdef CONFIG_PCI
2018static struct resource *find_parent_pci_resource(struct pci_dev* pdev,
2019 struct address_range *range)
2020{
2021 unsigned long mask;
2022 int i;
2023
2024 /* Check this one */
2025 mask = bus_space_to_resource_flags(range->space);
2026 for (i=0; i<DEVICE_COUNT_RESOURCE; i++) {
2027 if ((pdev->resource[i].flags & mask) == mask &&
2028 pdev->resource[i].start <= range->address &&
2029 pdev->resource[i].end > range->address) {
2030 if ((range->address + range->size - 1) > pdev->resource[i].end) {
2031 /* Add better message */
2032 printk(KERN_WARNING "PCI/OF resource overlap !\n");
2033 return NULL;
2034 }
2035 break;
2036 }
2037 }
2038 if (i == DEVICE_COUNT_RESOURCE)
2039 return NULL;
2040 return &pdev->resource[i];
2041}
2042
2043/*
2044 * Request an OF device resource. Currently handles child of PCI devices,
2045 * or other nodes attached to the root node. Ultimately, put some
2046 * link to resources in the OF node.
2047 */
2048struct resource *request_OF_resource(struct device_node* node, int index,
2049 const char* name_postfix)
2050{
2051 struct pci_dev* pcidev;
2052 u8 pci_bus, pci_devfn;
2053 unsigned long iomask;
2054 struct device_node* nd;
2055 struct resource* parent;
2056 struct resource *res = NULL;
2057 int nlen, plen;
2058
2059 if (index >= node->n_addrs)
2060 goto fail;
2061
2062 /* Sanity check on bus space */
2063 iomask = bus_space_to_resource_flags(node->addrs[index].space);
2064 if (iomask & IORESOURCE_MEM)
2065 parent = &iomem_resource;
2066 else if (iomask & IORESOURCE_IO)
2067 parent = &ioport_resource;
2068 else
2069 goto fail;
2070
2071 /* Find a PCI parent if any */
2072 nd = node;
2073 pcidev = NULL;
2074 while (nd) {
2075 if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
2076 pcidev = pci_find_slot(pci_bus, pci_devfn);
2077 if (pcidev) break;
2078 nd = nd->parent;
2079 }
2080 if (pcidev)
2081 parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
2082 if (!parent) {
2083 printk(KERN_WARNING "request_OF_resource(%s), parent not found\n",
2084 node->name);
2085 goto fail;
2086 }
2087 1806
2088 res = __request_region(parent, node->addrs[index].address,
2089 node->addrs[index].size, NULL);
2090 if (!res)
2091 goto fail;
2092 nlen = strlen(node->name);
2093 plen = name_postfix ? strlen(name_postfix) : 0;
2094 res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL);
2095 if (res->name) {
2096 strcpy((char *)res->name, node->name);
2097 if (plen)
2098 strcpy((char *)res->name+nlen, name_postfix);
2099 }
2100 return res;
2101fail:
2102 return NULL;
2103}
2104EXPORT_SYMBOL(request_OF_resource);
2105
2106int release_OF_resource(struct device_node *node, int index)
2107{
2108 struct pci_dev* pcidev;
2109 u8 pci_bus, pci_devfn;
2110 unsigned long iomask, start, end;
2111 struct device_node* nd;
2112 struct resource* parent;
2113 struct resource *res = NULL;
2114
2115 if (index >= node->n_addrs)
2116 return -EINVAL;
2117
2118 /* Sanity check on bus space */
2119 iomask = bus_space_to_resource_flags(node->addrs[index].space);
2120 if (iomask & IORESOURCE_MEM)
2121 parent = &iomem_resource;
2122 else if (iomask & IORESOURCE_IO)
2123 parent = &ioport_resource;
2124 else
2125 return -EINVAL;
2126
2127 /* Find a PCI parent if any */
2128 nd = node;
2129 pcidev = NULL;
2130 while(nd) {
2131 if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
2132 pcidev = pci_find_slot(pci_bus, pci_devfn);
2133 if (pcidev) break;
2134 nd = nd->parent;
2135 }
2136 if (pcidev)
2137 parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
2138 if (!parent) {
2139 printk(KERN_WARNING "release_OF_resource(%s), parent not found\n",
2140 node->name);
2141 return -ENODEV;
2142 }
2143
2144 /* Find us in the parent and its childs */
2145 res = parent->child;
2146 start = node->addrs[index].address;
2147 end = start + node->addrs[index].size - 1;
2148 while (res) {
2149 if (res->start == start && res->end == end &&
2150 (res->flags & IORESOURCE_BUSY))
2151 break;
2152 if (res->start <= start && res->end >= end)
2153 res = res->child;
2154 else
2155 res = res->sibling;
2156 }
2157 if (!res)
2158 return -ENODEV;
2159
2160 if (res->name) {
2161 kfree(res->name);
2162 res->name = NULL;
2163 }
2164 release_resource(res);
2165 kfree(res);
2166
2167 return 0;
2168}
2169EXPORT_SYMBOL(release_OF_resource);
2170#endif /* CONFIG_PCI */
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index bcdc209dca85..e381f2fc121c 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -192,6 +192,11 @@ static unsigned long __initdata alloc_bottom;
192static unsigned long __initdata rmo_top; 192static unsigned long __initdata rmo_top;
193static unsigned long __initdata ram_top; 193static unsigned long __initdata ram_top;
194 194
195#ifdef CONFIG_KEXEC
196static unsigned long __initdata prom_crashk_base;
197static unsigned long __initdata prom_crashk_size;
198#endif
199
195static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE]; 200static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
196static int __initdata mem_reserve_cnt; 201static int __initdata mem_reserve_cnt;
197 202
@@ -553,7 +558,8 @@ unsigned long prom_memparse(const char *ptr, const char **retptr)
553static void __init early_cmdline_parse(void) 558static void __init early_cmdline_parse(void)
554{ 559{
555 struct prom_t *_prom = &RELOC(prom); 560 struct prom_t *_prom = &RELOC(prom);
556 char *opt, *p; 561 const char *opt;
562 char *p;
557 int l = 0; 563 int l = 0;
558 564
559 RELOC(prom_cmd_line[0]) = 0; 565 RELOC(prom_cmd_line[0]) = 0;
@@ -590,6 +596,34 @@ static void __init early_cmdline_parse(void)
590 RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000); 596 RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
591#endif 597#endif
592 } 598 }
599
600#ifdef CONFIG_KEXEC
601 /*
602 * crashkernel=size@addr specifies the location to reserve for
603 * crash kernel.
604 */
605 opt = strstr(RELOC(prom_cmd_line), RELOC("crashkernel="));
606 if (opt) {
607 opt += 12;
608 RELOC(prom_crashk_size) = prom_memparse(opt, &opt);
609
610 if (ALIGN(RELOC(prom_crashk_size), 0x1000000) !=
611 RELOC(prom_crashk_size)) {
612 prom_printf("Warning: crashkernel size is not "
613 "aligned to 16MB\n");
614 }
615
616 /*
617 * At present, the crash kernel always run at 32MB.
618 * Just ignore whatever user passed.
619 */
620 RELOC(prom_crashk_base) = 0x2000000;
621 if (*opt == '@') {
622 prom_printf("Warning: PPC64 kdump kernel always runs "
623 "at 32 MB\n");
624 }
625 }
626#endif
593} 627}
594 628
595#ifdef CONFIG_PPC_PSERIES 629#ifdef CONFIG_PPC_PSERIES
@@ -1011,6 +1045,12 @@ static void __init prom_init_mem(void)
1011 prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high)); 1045 prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
1012 prom_printf(" rmo_top : %x\n", RELOC(rmo_top)); 1046 prom_printf(" rmo_top : %x\n", RELOC(rmo_top));
1013 prom_printf(" ram_top : %x\n", RELOC(ram_top)); 1047 prom_printf(" ram_top : %x\n", RELOC(ram_top));
1048#ifdef CONFIG_KEXEC
1049 if (RELOC(prom_crashk_base)) {
1050 prom_printf(" crashk_base : %x\n", RELOC(prom_crashk_base));
1051 prom_printf(" crashk_size : %x\n", RELOC(prom_crashk_size));
1052 }
1053#endif
1014} 1054}
1015 1055
1016 1056
@@ -1500,6 +1540,8 @@ static int __init prom_find_machine_type(void)
1500#ifdef CONFIG_PPC64 1540#ifdef CONFIG_PPC64
1501 if (strstr(p, RELOC("Momentum,Maple"))) 1541 if (strstr(p, RELOC("Momentum,Maple")))
1502 return PLATFORM_MAPLE; 1542 return PLATFORM_MAPLE;
1543 if (strstr(p, RELOC("IBM,CPB")))
1544 return PLATFORM_CELL;
1503#endif 1545#endif
1504 i += sl + 1; 1546 i += sl + 1;
1505 } 1547 }
@@ -1994,7 +2036,7 @@ static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
1994 if (r3 && r4 && r4 != 0xdeadbeef) { 2036 if (r3 && r4 && r4 != 0xdeadbeef) {
1995 unsigned long val; 2037 unsigned long val;
1996 2038
1997 RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3; 2039 RELOC(prom_initrd_start) = is_kernel_addr(r3) ? __pa(r3) : r3;
1998 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4; 2040 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
1999 2041
2000 val = RELOC(prom_initrd_start); 2042 val = RELOC(prom_initrd_start);
@@ -2094,6 +2136,10 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2094 */ 2136 */
2095 prom_init_mem(); 2137 prom_init_mem();
2096 2138
2139#ifdef CONFIG_KEXEC
2140 if (RELOC(prom_crashk_base))
2141 reserve_mem(RELOC(prom_crashk_base), RELOC(prom_crashk_size));
2142#endif
2097 /* 2143 /*
2098 * Determine which cpu is actually running right _now_ 2144 * Determine which cpu is actually running right _now_
2099 */ 2145 */
@@ -2150,6 +2196,16 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2150 } 2196 }
2151#endif 2197#endif
2152 2198
2199#ifdef CONFIG_KEXEC
2200 if (RELOC(prom_crashk_base)) {
2201 prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-base",
2202 PTRRELOC(&prom_crashk_base),
2203 sizeof(RELOC(prom_crashk_base)));
2204 prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-size",
2205 PTRRELOC(&prom_crashk_size),
2206 sizeof(RELOC(prom_crashk_size)));
2207 }
2208#endif
2153 /* 2209 /*
2154 * Fixup any known bugs in the device-tree 2210 * Fixup any known bugs in the device-tree
2155 */ 2211 */
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
new file mode 100644
index 000000000000..309ae1d5fa77
--- /dev/null
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -0,0 +1,547 @@
1#undef DEBUG
2
3#include <linux/kernel.h>
4#include <linux/string.h>
5#include <linux/pci_regs.h>
6#include <linux/module.h>
7#include <linux/ioport.h>
8#include <asm/prom.h>
9#include <asm/pci-bridge.h>
10
11#ifdef DEBUG
12#define DBG(fmt...) do { printk(fmt); } while(0)
13#else
14#define DBG(fmt...) do { } while(0)
15#endif
16
17#ifdef CONFIG_PPC64
18#define PRu64 "%lx"
19#else
20#define PRu64 "%llx"
21#endif
22
23/* Max address size we deal with */
24#define OF_MAX_ADDR_CELLS 4
25#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
26 (ns) > 0)
27
28/* Debug utility */
29#ifdef DEBUG
30static void of_dump_addr(const char *s, u32 *addr, int na)
31{
32 printk("%s", s);
33 while(na--)
34 printk(" %08x", *(addr++));
35 printk("\n");
36}
37#else
38static void of_dump_addr(const char *s, u32 *addr, int na) { }
39#endif
40
41/* Read a big address */
42static inline u64 of_read_addr(u32 *cell, int size)
43{
44 u64 r = 0;
45 while (size--)
46 r = (r << 32) | *(cell++);
47 return r;
48}
49
50/* Callbacks for bus specific translators */
51struct of_bus {
52 const char *name;
53 const char *addresses;
54 int (*match)(struct device_node *parent);
55 void (*count_cells)(struct device_node *child,
56 int *addrc, int *sizec);
57 u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna);
58 int (*translate)(u32 *addr, u64 offset, int na);
59 unsigned int (*get_flags)(u32 *addr);
60};
61
62
63/*
64 * Default translator (generic bus)
65 */
66
67static void of_bus_default_count_cells(struct device_node *dev,
68 int *addrc, int *sizec)
69{
70 if (addrc)
71 *addrc = prom_n_addr_cells(dev);
72 if (sizec)
73 *sizec = prom_n_size_cells(dev);
74}
75
76static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna)
77{
78 u64 cp, s, da;
79
80 cp = of_read_addr(range, na);
81 s = of_read_addr(range + na + pna, ns);
82 da = of_read_addr(addr, na);
83
84 DBG("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n",
85 cp, s, da);
86
87 if (da < cp || da >= (cp + s))
88 return OF_BAD_ADDR;
89 return da - cp;
90}
91
92static int of_bus_default_translate(u32 *addr, u64 offset, int na)
93{
94 u64 a = of_read_addr(addr, na);
95 memset(addr, 0, na * 4);
96 a += offset;
97 if (na > 1)
98 addr[na - 2] = a >> 32;
99 addr[na - 1] = a & 0xffffffffu;
100
101 return 0;
102}
103
104static unsigned int of_bus_default_get_flags(u32 *addr)
105{
106 return IORESOURCE_MEM;
107}
108
109
110/*
111 * PCI bus specific translator
112 */
113
114static int of_bus_pci_match(struct device_node *np)
115{
116 return !strcmp(np->type, "pci");
117}
118
119static void of_bus_pci_count_cells(struct device_node *np,
120 int *addrc, int *sizec)
121{
122 if (addrc)
123 *addrc = 3;
124 if (sizec)
125 *sizec = 2;
126}
127
128static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna)
129{
130 u64 cp, s, da;
131
132 /* Check address type match */
133 if ((addr[0] ^ range[0]) & 0x03000000)
134 return OF_BAD_ADDR;
135
136 /* Read address values, skipping high cell */
137 cp = of_read_addr(range + 1, na - 1);
138 s = of_read_addr(range + na + pna, ns);
139 da = of_read_addr(addr + 1, na - 1);
140
141 DBG("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
142
143 if (da < cp || da >= (cp + s))
144 return OF_BAD_ADDR;
145 return da - cp;
146}
147
148static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
149{
150 return of_bus_default_translate(addr + 1, offset, na - 1);
151}
152
153static unsigned int of_bus_pci_get_flags(u32 *addr)
154{
155 unsigned int flags = 0;
156 u32 w = addr[0];
157
158 switch((w >> 24) & 0x03) {
159 case 0x01:
160 flags |= IORESOURCE_IO;
161 case 0x02: /* 32 bits */
162 case 0x03: /* 64 bits */
163 flags |= IORESOURCE_MEM;
164 }
165 if (w & 0x40000000)
166 flags |= IORESOURCE_PREFETCH;
167 return flags;
168}
169
170/*
171 * ISA bus specific translator
172 */
173
174static int of_bus_isa_match(struct device_node *np)
175{
176 return !strcmp(np->name, "isa");
177}
178
179static void of_bus_isa_count_cells(struct device_node *child,
180 int *addrc, int *sizec)
181{
182 if (addrc)
183 *addrc = 2;
184 if (sizec)
185 *sizec = 1;
186}
187
188static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna)
189{
190 u64 cp, s, da;
191
192 /* Check address type match */
193 if ((addr[0] ^ range[0]) & 0x00000001)
194 return OF_BAD_ADDR;
195
196 /* Read address values, skipping high cell */
197 cp = of_read_addr(range + 1, na - 1);
198 s = of_read_addr(range + na + pna, ns);
199 da = of_read_addr(addr + 1, na - 1);
200
201 DBG("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
202
203 if (da < cp || da >= (cp + s))
204 return OF_BAD_ADDR;
205 return da - cp;
206}
207
208static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
209{
210 return of_bus_default_translate(addr + 1, offset, na - 1);
211}
212
213static unsigned int of_bus_isa_get_flags(u32 *addr)
214{
215 unsigned int flags = 0;
216 u32 w = addr[0];
217
218 if (w & 1)
219 flags |= IORESOURCE_IO;
220 else
221 flags |= IORESOURCE_MEM;
222 return flags;
223}
224
225
226/*
227 * Array of bus specific translators
228 */
229
230static struct of_bus of_busses[] = {
231 /* PCI */
232 {
233 .name = "pci",
234 .addresses = "assigned-addresses",
235 .match = of_bus_pci_match,
236 .count_cells = of_bus_pci_count_cells,
237 .map = of_bus_pci_map,
238 .translate = of_bus_pci_translate,
239 .get_flags = of_bus_pci_get_flags,
240 },
241 /* ISA */
242 {
243 .name = "isa",
244 .addresses = "reg",
245 .match = of_bus_isa_match,
246 .count_cells = of_bus_isa_count_cells,
247 .map = of_bus_isa_map,
248 .translate = of_bus_isa_translate,
249 .get_flags = of_bus_isa_get_flags,
250 },
251 /* Default */
252 {
253 .name = "default",
254 .addresses = "reg",
255 .match = NULL,
256 .count_cells = of_bus_default_count_cells,
257 .map = of_bus_default_map,
258 .translate = of_bus_default_translate,
259 .get_flags = of_bus_default_get_flags,
260 },
261};
262
263static struct of_bus *of_match_bus(struct device_node *np)
264{
265 int i;
266
267 for (i = 0; i < ARRAY_SIZE(of_busses); i ++)
268 if (!of_busses[i].match || of_busses[i].match(np))
269 return &of_busses[i];
270 BUG();
271 return NULL;
272}
273
274static int of_translate_one(struct device_node *parent, struct of_bus *bus,
275 struct of_bus *pbus, u32 *addr,
276 int na, int ns, int pna)
277{
278 u32 *ranges;
279 unsigned int rlen;
280 int rone;
281 u64 offset = OF_BAD_ADDR;
282
283 /* Normally, an absence of a "ranges" property means we are
284 * crossing a non-translatable boundary, and thus the addresses
285 * below the current not cannot be converted to CPU physical ones.
286 * Unfortunately, while this is very clear in the spec, it's not
287 * what Apple understood, and they do have things like /uni-n or
288 * /ht nodes with no "ranges" property and a lot of perfectly
289 * useable mapped devices below them. Thus we treat the absence of
290 * "ranges" as equivalent to an empty "ranges" property which means
291 * a 1:1 translation at that level. It's up to the caller not to try
292 * to translate addresses that aren't supposed to be translated in
293 * the first place. --BenH.
294 */
295 ranges = (u32 *)get_property(parent, "ranges", &rlen);
296 if (ranges == NULL || rlen == 0) {
297 offset = of_read_addr(addr, na);
298 memset(addr, 0, pna * 4);
299 DBG("OF: no ranges, 1:1 translation\n");
300 goto finish;
301 }
302
303 DBG("OF: walking ranges...\n");
304
305 /* Now walk through the ranges */
306 rlen /= 4;
307 rone = na + pna + ns;
308 for (; rlen >= rone; rlen -= rone, ranges += rone) {
309 offset = bus->map(addr, ranges, na, ns, pna);
310 if (offset != OF_BAD_ADDR)
311 break;
312 }
313 if (offset == OF_BAD_ADDR) {
314 DBG("OF: not found !\n");
315 return 1;
316 }
317 memcpy(addr, ranges + na, 4 * pna);
318
319 finish:
320 of_dump_addr("OF: parent translation for:", addr, pna);
321 DBG("OF: with offset: "PRu64"\n", offset);
322
323 /* Translate it into parent bus space */
324 return pbus->translate(addr, offset, pna);
325}
326
327
328/*
329 * Translate an address from the device-tree into a CPU physical address,
330 * this walks up the tree and applies the various bus mappings on the
331 * way.
332 *
333 * Note: We consider that crossing any level with #size-cells == 0 to mean
334 * that translation is impossible (that is we are not dealing with a value
335 * that can be mapped to a cpu physical address). This is not really specified
336 * that way, but this is traditionally the way IBM at least do things
337 */
338u64 of_translate_address(struct device_node *dev, u32 *in_addr)
339{
340 struct device_node *parent = NULL;
341 struct of_bus *bus, *pbus;
342 u32 addr[OF_MAX_ADDR_CELLS];
343 int na, ns, pna, pns;
344 u64 result = OF_BAD_ADDR;
345
346 DBG("OF: ** translation for device %s **\n", dev->full_name);
347
348 /* Increase refcount at current level */
349 of_node_get(dev);
350
351 /* Get parent & match bus type */
352 parent = of_get_parent(dev);
353 if (parent == NULL)
354 goto bail;
355 bus = of_match_bus(parent);
356
357 /* Cound address cells & copy address locally */
358 bus->count_cells(dev, &na, &ns);
359 if (!OF_CHECK_COUNTS(na, ns)) {
360 printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
361 dev->full_name);
362 goto bail;
363 }
364 memcpy(addr, in_addr, na * 4);
365
366 DBG("OF: bus is %s (na=%d, ns=%d) on %s\n",
367 bus->name, na, ns, parent->full_name);
368 of_dump_addr("OF: translating address:", addr, na);
369
370 /* Translate */
371 for (;;) {
372 /* Switch to parent bus */
373 of_node_put(dev);
374 dev = parent;
375 parent = of_get_parent(dev);
376
377 /* If root, we have finished */
378 if (parent == NULL) {
379 DBG("OF: reached root node\n");
380 result = of_read_addr(addr, na);
381 break;
382 }
383
384 /* Get new parent bus and counts */
385 pbus = of_match_bus(parent);
386 pbus->count_cells(dev, &pna, &pns);
387 if (!OF_CHECK_COUNTS(pna, pns)) {
388 printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
389 dev->full_name);
390 break;
391 }
392
393 DBG("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
394 pbus->name, pna, pns, parent->full_name);
395
396 /* Apply bus translation */
397 if (of_translate_one(dev, bus, pbus, addr, na, ns, pna))
398 break;
399
400 /* Complete the move up one level */
401 na = pna;
402 ns = pns;
403 bus = pbus;
404
405 of_dump_addr("OF: one level translation:", addr, na);
406 }
407 bail:
408 of_node_put(parent);
409 of_node_put(dev);
410
411 return result;
412}
413EXPORT_SYMBOL(of_translate_address);
414
415u32 *of_get_address(struct device_node *dev, int index, u64 *size,
416 unsigned int *flags)
417{
418 u32 *prop;
419 unsigned int psize;
420 struct device_node *parent;
421 struct of_bus *bus;
422 int onesize, i, na, ns;
423
424 /* Get parent & match bus type */
425 parent = of_get_parent(dev);
426 if (parent == NULL)
427 return NULL;
428 bus = of_match_bus(parent);
429 bus->count_cells(dev, &na, &ns);
430 of_node_put(parent);
431 if (!OF_CHECK_COUNTS(na, ns))
432 return NULL;
433
434 /* Get "reg" or "assigned-addresses" property */
435 prop = (u32 *)get_property(dev, bus->addresses, &psize);
436 if (prop == NULL)
437 return NULL;
438 psize /= 4;
439
440 onesize = na + ns;
441 for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
442 if (i == index) {
443 if (size)
444 *size = of_read_addr(prop + na, ns);
445 if (flags)
446 *flags = bus->get_flags(prop);
447 return prop;
448 }
449 return NULL;
450}
451EXPORT_SYMBOL(of_get_address);
452
453u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
454 unsigned int *flags)
455{
456 u32 *prop;
457 unsigned int psize;
458 struct device_node *parent;
459 struct of_bus *bus;
460 int onesize, i, na, ns;
461
462 /* Get parent & match bus type */
463 parent = of_get_parent(dev);
464 if (parent == NULL)
465 return NULL;
466 bus = of_match_bus(parent);
467 if (strcmp(bus->name, "pci"))
468 return NULL;
469 bus->count_cells(dev, &na, &ns);
470 of_node_put(parent);
471 if (!OF_CHECK_COUNTS(na, ns))
472 return NULL;
473
474 /* Get "reg" or "assigned-addresses" property */
475 prop = (u32 *)get_property(dev, bus->addresses, &psize);
476 if (prop == NULL)
477 return NULL;
478 psize /= 4;
479
480 onesize = na + ns;
481 for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
482 if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
483 if (size)
484 *size = of_read_addr(prop + na, ns);
485 if (flags)
486 *flags = bus->get_flags(prop);
487 return prop;
488 }
489 return NULL;
490}
491EXPORT_SYMBOL(of_get_pci_address);
492
493static int __of_address_to_resource(struct device_node *dev, u32 *addrp,
494 u64 size, unsigned int flags,
495 struct resource *r)
496{
497 u64 taddr;
498
499 if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
500 return -EINVAL;
501 taddr = of_translate_address(dev, addrp);
502 if (taddr == OF_BAD_ADDR)
503 return -EINVAL;
504 memset(r, 0, sizeof(struct resource));
505 if (flags & IORESOURCE_IO) {
506 unsigned long port;
507 port = pci_address_to_pio(taddr);
508 if (port == (unsigned long)-1)
509 return -EINVAL;
510 r->start = port;
511 r->end = port + size - 1;
512 } else {
513 r->start = taddr;
514 r->end = taddr + size - 1;
515 }
516 r->flags = flags;
517 r->name = dev->name;
518 return 0;
519}
520
521int of_address_to_resource(struct device_node *dev, int index,
522 struct resource *r)
523{
524 u32 *addrp;
525 u64 size;
526 unsigned int flags;
527
528 addrp = of_get_address(dev, index, &size, &flags);
529 if (addrp == NULL)
530 return -EINVAL;
531 return __of_address_to_resource(dev, addrp, size, flags, r);
532}
533EXPORT_SYMBOL_GPL(of_address_to_resource);
534
535int of_pci_address_to_resource(struct device_node *dev, int bar,
536 struct resource *r)
537{
538 u32 *addrp;
539 u64 size;
540 unsigned int flags;
541
542 addrp = of_get_pci_address(dev, bar, &size, &flags);
543 if (addrp == NULL)
544 return -EINVAL;
545 return __of_address_to_resource(dev, addrp, size, flags, r);
546}
547EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 60dec2401c26..45b8109951fe 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -188,39 +188,19 @@ int is_python(struct device_node *dev)
188 return 0; 188 return 0;
189} 189}
190 190
191static int get_phb_reg_prop(struct device_node *dev, 191static void python_countermeasures(struct device_node *dev)
192 unsigned int addr_size_words,
193 struct reg_property64 *reg)
194{ 192{
195 unsigned int *ui_ptr = NULL, len; 193 struct resource registers;
196
197 /* Found a PHB, now figure out where his registers are mapped. */
198 ui_ptr = (unsigned int *)get_property(dev, "reg", &len);
199 if (ui_ptr == NULL)
200 return 1;
201
202 if (addr_size_words == 1) {
203 reg->address = ((struct reg_property32 *)ui_ptr)->address;
204 reg->size = ((struct reg_property32 *)ui_ptr)->size;
205 } else {
206 *reg = *((struct reg_property64 *)ui_ptr);
207 }
208
209 return 0;
210}
211
212static void python_countermeasures(struct device_node *dev,
213 unsigned int addr_size_words)
214{
215 struct reg_property64 reg_struct;
216 void __iomem *chip_regs; 194 void __iomem *chip_regs;
217 volatile u32 val; 195 volatile u32 val;
218 196
219 if (get_phb_reg_prop(dev, addr_size_words, &reg_struct)) 197 if (of_address_to_resource(dev, 0, &registers)) {
198 printk(KERN_ERR "Can't get address for Python workarounds !\n");
220 return; 199 return;
200 }
221 201
222 /* Python's register file is 1 MB in size. */ 202 /* Python's register file is 1 MB in size. */
223 chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000); 203 chip_regs = ioremap(registers.start & ~(0xfffffUL), 0x100000);
224 204
225 /* 205 /*
226 * Firmware doesn't always clear this bit which is critical 206 * Firmware doesn't always clear this bit which is critical
@@ -301,11 +281,10 @@ static int phb_set_bus_ranges(struct device_node *dev,
301} 281}
302 282
303static int __devinit setup_phb(struct device_node *dev, 283static int __devinit setup_phb(struct device_node *dev,
304 struct pci_controller *phb, 284 struct pci_controller *phb)
305 unsigned int addr_size_words)
306{ 285{
307 if (is_python(dev)) 286 if (is_python(dev))
308 python_countermeasures(dev, addr_size_words); 287 python_countermeasures(dev);
309 288
310 if (phb_set_bus_ranges(dev, phb)) 289 if (phb_set_bus_ranges(dev, phb))
311 return 1; 290 return 1;
@@ -320,8 +299,8 @@ unsigned long __init find_and_init_phbs(void)
320{ 299{
321 struct device_node *node; 300 struct device_node *node;
322 struct pci_controller *phb; 301 struct pci_controller *phb;
323 unsigned int root_size_cells = 0;
324 unsigned int index; 302 unsigned int index;
303 unsigned int root_size_cells = 0;
325 unsigned int *opprop = NULL; 304 unsigned int *opprop = NULL;
326 struct device_node *root = of_find_node_by_path("/"); 305 struct device_node *root = of_find_node_by_path("/");
327 306
@@ -343,10 +322,11 @@ unsigned long __init find_and_init_phbs(void)
343 phb = pcibios_alloc_controller(node); 322 phb = pcibios_alloc_controller(node);
344 if (!phb) 323 if (!phb)
345 continue; 324 continue;
346 setup_phb(node, phb, root_size_cells); 325 setup_phb(node, phb);
347 pci_process_bridge_OF_ranges(phb, node, 0); 326 pci_process_bridge_OF_ranges(phb, node, 0);
348 pci_setup_phb_io(phb, index == 0); 327 pci_setup_phb_io(phb, index == 0);
349#ifdef CONFIG_PPC_PSERIES 328#ifdef CONFIG_PPC_PSERIES
329 /* XXX This code need serious fixing ... --BenH */
350 if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) { 330 if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
351 int addr = root_size_cells * (index + 2) - 1; 331 int addr = root_size_cells * (index + 2) - 1;
352 mpic_assign_isu(pSeries_mpic, index, opprop[addr]); 332 mpic_assign_isu(pSeries_mpic, index, opprop[addr]);
@@ -381,22 +361,17 @@ unsigned long __init find_and_init_phbs(void)
381 361
382struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) 362struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
383{ 363{
384 struct device_node *root = of_find_node_by_path("/");
385 unsigned int root_size_cells = 0;
386 struct pci_controller *phb; 364 struct pci_controller *phb;
387 int primary; 365 int primary;
388 366
389 root_size_cells = prom_n_size_cells(root);
390
391 primary = list_empty(&hose_list); 367 primary = list_empty(&hose_list);
392 phb = pcibios_alloc_controller(dn); 368 phb = pcibios_alloc_controller(dn);
393 if (!phb) 369 if (!phb)
394 return NULL; 370 return NULL;
395 setup_phb(dn, phb, root_size_cells); 371 setup_phb(dn, phb);
396 pci_process_bridge_OF_ranges(phb, dn, primary); 372 pci_process_bridge_OF_ranges(phb, dn, primary);
397 373
398 pci_setup_phb_io_dynamic(phb, primary); 374 pci_setup_phb_io_dynamic(phb, primary);
399 of_node_put(root);
400 375
401 pci_devs_phb_init_dynamic(phb); 376 pci_devs_phb_init_dynamic(phb);
402 scan_phb(phb); 377 scan_phb(phb);
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index bd3eb4292b53..d5c52fae023a 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -93,8 +93,8 @@ EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
93/* also used by kexec */ 93/* also used by kexec */
94void machine_shutdown(void) 94void machine_shutdown(void)
95{ 95{
96 if (ppc_md.nvram_sync) 96 if (ppc_md.machine_shutdown)
97 ppc_md.nvram_sync(); 97 ppc_md.machine_shutdown();
98} 98}
99 99
100void machine_restart(char *cmd) 100void machine_restart(char *cmd)
@@ -294,129 +294,6 @@ struct seq_operations cpuinfo_op = {
294 .show = show_cpuinfo, 294 .show = show_cpuinfo,
295}; 295};
296 296
297#ifdef CONFIG_PPC_MULTIPLATFORM
298static int __init set_preferred_console(void)
299{
300 struct device_node *prom_stdout = NULL;
301 char *name;
302 u32 *spd;
303 int offset = 0;
304
305 DBG(" -> set_preferred_console()\n");
306
307 /* The user has requested a console so this is already set up. */
308 if (strstr(saved_command_line, "console=")) {
309 DBG(" console was specified !\n");
310 return -EBUSY;
311 }
312
313 if (!of_chosen) {
314 DBG(" of_chosen is NULL !\n");
315 return -ENODEV;
316 }
317 /* We are getting a weird phandle from OF ... */
318 /* ... So use the full path instead */
319 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
320 if (name == NULL) {
321 DBG(" no linux,stdout-path !\n");
322 return -ENODEV;
323 }
324 prom_stdout = of_find_node_by_path(name);
325 if (!prom_stdout) {
326 DBG(" can't find stdout package %s !\n", name);
327 return -ENODEV;
328 }
329 DBG("stdout is %s\n", prom_stdout->full_name);
330
331 name = (char *)get_property(prom_stdout, "name", NULL);
332 if (!name) {
333 DBG(" stdout package has no name !\n");
334 goto not_found;
335 }
336 spd = (u32 *)get_property(prom_stdout, "current-speed", NULL);
337
338 if (0)
339 ;
340#ifdef CONFIG_SERIAL_8250_CONSOLE
341 else if (strcmp(name, "serial") == 0) {
342 int i;
343 u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i);
344 if (i > 8) {
345 switch (reg[1]) {
346 case 0x3f8:
347 offset = 0;
348 break;
349 case 0x2f8:
350 offset = 1;
351 break;
352 case 0x898:
353 offset = 2;
354 break;
355 case 0x890:
356 offset = 3;
357 break;
358 default:
359 /* We dont recognise the serial port */
360 goto not_found;
361 }
362 }
363 }
364#endif /* CONFIG_SERIAL_8250_CONSOLE */
365#ifdef CONFIG_PPC_PSERIES
366 else if (strcmp(name, "vty") == 0) {
367 u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL);
368 char *compat = (char *)get_property(prom_stdout, "compatible", NULL);
369
370 if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) {
371 /* Host Virtual Serial Interface */
372 switch (reg[0]) {
373 case 0x30000000:
374 offset = 0;
375 break;
376 case 0x30000001:
377 offset = 1;
378 break;
379 default:
380 goto not_found;
381 }
382 of_node_put(prom_stdout);
383 DBG("Found hvsi console at offset %d\n", offset);
384 return add_preferred_console("hvsi", offset, NULL);
385 } else {
386 /* pSeries LPAR virtual console */
387 of_node_put(prom_stdout);
388 DBG("Found hvc console\n");
389 return add_preferred_console("hvc", 0, NULL);
390 }
391 }
392#endif /* CONFIG_PPC_PSERIES */
393#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
394 else if (strcmp(name, "ch-a") == 0)
395 offset = 0;
396 else if (strcmp(name, "ch-b") == 0)
397 offset = 1;
398#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
399 else
400 goto not_found;
401 of_node_put(prom_stdout);
402
403 DBG("Found serial console at ttyS%d\n", offset);
404
405 if (spd) {
406 static char __initdata opt[16];
407 sprintf(opt, "%d", *spd);
408 return add_preferred_console("ttyS", offset, opt);
409 } else
410 return add_preferred_console("ttyS", offset, NULL);
411
412 not_found:
413 DBG("No preferred console found !\n");
414 of_node_put(prom_stdout);
415 return -ENODEV;
416}
417console_initcall(set_preferred_console);
418#endif /* CONFIG_PPC_MULTIPLATFORM */
419
420void __init check_for_initrd(void) 297void __init check_for_initrd(void)
421{ 298{
422#ifdef CONFIG_BLK_DEV_INITRD 299#ifdef CONFIG_BLK_DEV_INITRD
@@ -442,7 +319,7 @@ void __init check_for_initrd(void)
442 /* If we were passed an initrd, set the ROOT_DEV properly if the values 319 /* If we were passed an initrd, set the ROOT_DEV properly if the values
443 * look sensible. If not, clear initrd reference. 320 * look sensible. If not, clear initrd reference.
444 */ 321 */
445 if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE && 322 if (is_kernel_addr(initrd_start) && is_kernel_addr(initrd_end) &&
446 initrd_end > initrd_start) 323 initrd_end > initrd_start)
447 ROOT_DEV = Root_RAM0; 324 ROOT_DEV = Root_RAM0;
448 else 325 else
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index e5694335bf10..e5d285adb496 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -39,6 +39,8 @@
39#include <asm/nvram.h> 39#include <asm/nvram.h>
40#include <asm/xmon.h> 40#include <asm/xmon.h>
41#include <asm/time.h> 41#include <asm/time.h>
42#include <asm/serial.h>
43#include <asm/udbg.h>
42 44
43#include "setup.h" 45#include "setup.h"
44 46
@@ -172,12 +174,23 @@ void __init platform_init(void)
172 */ 174 */
173void __init machine_init(unsigned long dt_ptr, unsigned long phys) 175void __init machine_init(unsigned long dt_ptr, unsigned long phys)
174{ 176{
177 /* If btext is enabled, we might have a BAT setup for early display,
178 * thus we do enable some very basic udbg output
179 */
180#ifdef CONFIG_BOOTX_TEXT
181 udbg_putc = btext_drawchar;
182#endif
183
184 /* Do some early initialization based on the flat device tree */
175 early_init_devtree(__va(dt_ptr)); 185 early_init_devtree(__va(dt_ptr));
176 186
187 /* Check default command line */
177#ifdef CONFIG_CMDLINE 188#ifdef CONFIG_CMDLINE
178 strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); 189 if (cmd_line[0] == 0)
190 strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
179#endif /* CONFIG_CMDLINE */ 191#endif /* CONFIG_CMDLINE */
180 192
193 /* Base init based on machine type */
181 platform_init(); 194 platform_init();
182 195
183#ifdef CONFIG_6xx 196#ifdef CONFIG_6xx
@@ -282,25 +295,22 @@ void __init setup_arch(char **cmdline_p)
282 295
283 unflatten_device_tree(); 296 unflatten_device_tree();
284 check_for_initrd(); 297 check_for_initrd();
285 finish_device_tree();
286 298
287 smp_setup_cpu_maps(); 299 if (ppc_md.init_early)
300 ppc_md.init_early();
288 301
289#ifdef CONFIG_BOOTX_TEXT 302#ifdef CONFIG_SERIAL_8250
290 init_boot_display(); 303 find_legacy_serial_ports();
291#endif 304#endif
305 finish_device_tree();
292 306
293#ifdef CONFIG_PPC_PMAC 307 smp_setup_cpu_maps();
294 /* This could be called "early setup arch", it must be done
295 * now because xmon need it
296 */
297 if (_machine == _MACH_Pmac)
298 pmac_feature_init(); /* New cool way */
299#endif
300 308
301#ifdef CONFIG_XMON_DEFAULT 309#ifdef CONFIG_XMON_DEFAULT
302 xmon_init(1); 310 xmon_init(1);
303#endif 311#endif
312 /* Register early console */
313 register_early_udbg_console();
304 314
305#if defined(CONFIG_KGDB) 315#if defined(CONFIG_KGDB)
306 if (ppc_md.kgdb_map_scc) 316 if (ppc_md.kgdb_map_scc)
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index e3fb78397dc6..98e9f0595dd8 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -34,6 +34,7 @@
34#include <linux/serial.h> 34#include <linux/serial.h>
35#include <linux/serial_8250.h> 35#include <linux/serial_8250.h>
36#include <asm/io.h> 36#include <asm/io.h>
37#include <asm/kdump.h>
37#include <asm/prom.h> 38#include <asm/prom.h>
38#include <asm/processor.h> 39#include <asm/processor.h>
39#include <asm/pgtable.h> 40#include <asm/pgtable.h>
@@ -268,6 +269,10 @@ void __init early_setup(unsigned long dt_ptr)
268 } 269 }
269 ppc_md = **mach; 270 ppc_md = **mach;
270 271
272#ifdef CONFIG_CRASH_DUMP
273 kdump_setup();
274#endif
275
271 DBG("Found, Initializing memory management...\n"); 276 DBG("Found, Initializing memory management...\n");
272 277
273 /* 278 /*
@@ -317,6 +322,7 @@ void early_setup_secondary(void)
317void smp_release_cpus(void) 322void smp_release_cpus(void)
318{ 323{
319 extern unsigned long __secondary_hold_spinloop; 324 extern unsigned long __secondary_hold_spinloop;
325 unsigned long *ptr;
320 326
321 DBG(" -> smp_release_cpus()\n"); 327 DBG(" -> smp_release_cpus()\n");
322 328
@@ -327,7 +333,9 @@ void smp_release_cpus(void)
327 * This is useless but harmless on iSeries, secondaries are already 333 * This is useless but harmless on iSeries, secondaries are already
328 * waiting on their paca spinloops. */ 334 * waiting on their paca spinloops. */
329 335
330 __secondary_hold_spinloop = 1; 336 ptr = (unsigned long *)((unsigned long)&__secondary_hold_spinloop
337 - PHYSICAL_START);
338 *ptr = 1;
331 mb(); 339 mb();
332 340
333 DBG(" <- smp_release_cpus()\n"); 341 DBG(" <- smp_release_cpus()\n");
@@ -459,16 +467,21 @@ void __init setup_system(void)
459 */ 467 */
460 ppc_md.init_early(); 468 ppc_md.init_early();
461 469
470 /*
471 * We can discover serial ports now since the above did setup the
472 * hash table management for us, thus ioremap works. We do that early
473 * so that further code can be debugged
474 */
475#ifdef CONFIG_SERIAL_8250
476 find_legacy_serial_ports();
477#endif
478
462 /* 479 /*
463 * "Finish" the device-tree, that is do the actual parsing of 480 * "Finish" the device-tree, that is do the actual parsing of
464 * some of the properties like the interrupt map 481 * some of the properties like the interrupt map
465 */ 482 */
466 finish_device_tree(); 483 finish_device_tree();
467 484
468#ifdef CONFIG_BOOTX_TEXT
469 init_boot_display();
470#endif
471
472 /* 485 /*
473 * Initialize xmon 486 * Initialize xmon
474 */ 487 */
@@ -507,6 +520,9 @@ void __init setup_system(void)
507 ppc64_caches.iline_size); 520 ppc64_caches.iline_size);
508 printk("htab_address = 0x%p\n", htab_address); 521 printk("htab_address = 0x%p\n", htab_address);
509 printk("htab_hash_mask = 0x%lx\n", htab_hash_mask); 522 printk("htab_hash_mask = 0x%lx\n", htab_hash_mask);
523#if PHYSICAL_START > 0
524 printk("physical_start = 0x%x\n", PHYSICAL_START);
525#endif
510 printk("-----------------------------------------------------\n"); 526 printk("-----------------------------------------------------\n");
511 527
512 mm_init_ppc64(); 528 mm_init_ppc64();
@@ -657,187 +673,6 @@ void ppc64_terminate_msg(unsigned int src, const char *msg)
657 printk("[terminate]%04x %s\n", src, msg); 673 printk("[terminate]%04x %s\n", src, msg);
658} 674}
659 675
660#ifndef CONFIG_PPC_ISERIES
661/*
662 * This function can be used by platforms to "find" legacy serial ports.
663 * It works for "serial" nodes under an "isa" node, and will try to
664 * respect the "ibm,aix-loc" property if any. It works with up to 8
665 * ports.
666 */
667
668#define MAX_LEGACY_SERIAL_PORTS 8
669static struct plat_serial8250_port serial_ports[MAX_LEGACY_SERIAL_PORTS+1];
670static unsigned int old_serial_count;
671
672void __init generic_find_legacy_serial_ports(u64 *physport,
673 unsigned int *default_speed)
674{
675 struct device_node *np;
676 u32 *sizeprop;
677
678 struct isa_reg_property {
679 u32 space;
680 u32 address;
681 u32 size;
682 };
683 struct pci_reg_property {
684 struct pci_address addr;
685 u32 size_hi;
686 u32 size_lo;
687 };
688
689 DBG(" -> generic_find_legacy_serial_port()\n");
690
691 *physport = 0;
692 if (default_speed)
693 *default_speed = 0;
694
695 np = of_find_node_by_path("/");
696 if (!np)
697 return;
698
699 /* First fill our array */
700 for (np = NULL; (np = of_find_node_by_type(np, "serial"));) {
701 struct device_node *isa, *pci;
702 struct isa_reg_property *reg;
703 unsigned long phys_size, addr_size, io_base;
704 u32 *rangesp;
705 u32 *interrupts, *clk, *spd;
706 char *typep;
707 int index, rlen, rentsize;
708
709 /* Ok, first check if it's under an "isa" parent */
710 isa = of_get_parent(np);
711 if (!isa || strcmp(isa->name, "isa")) {
712 DBG("%s: no isa parent found\n", np->full_name);
713 continue;
714 }
715
716 /* Now look for an "ibm,aix-loc" property that gives us ordering
717 * if any...
718 */
719 typep = (char *)get_property(np, "ibm,aix-loc", NULL);
720
721 /* Get the ISA port number */
722 reg = (struct isa_reg_property *)get_property(np, "reg", NULL);
723 if (reg == NULL)
724 goto next_port;
725 /* We assume the interrupt number isn't translated ... */
726 interrupts = (u32 *)get_property(np, "interrupts", NULL);
727 /* get clock freq. if present */
728 clk = (u32 *)get_property(np, "clock-frequency", NULL);
729 /* get default speed if present */
730 spd = (u32 *)get_property(np, "current-speed", NULL);
731 /* Default to locate at end of array */
732 index = old_serial_count; /* end of the array by default */
733
734 /* If we have a location index, then use it */
735 if (typep && *typep == 'S') {
736 index = simple_strtol(typep+1, NULL, 0) - 1;
737 /* if index is out of range, use end of array instead */
738 if (index >= MAX_LEGACY_SERIAL_PORTS)
739 index = old_serial_count;
740 /* if our index is still out of range, that mean that
741 * array is full, we could scan for a free slot but that
742 * make little sense to bother, just skip the port
743 */
744 if (index >= MAX_LEGACY_SERIAL_PORTS)
745 goto next_port;
746 if (index >= old_serial_count)
747 old_serial_count = index + 1;
748 /* Check if there is a port who already claimed our slot */
749 if (serial_ports[index].iobase != 0) {
750 /* if we still have some room, move it, else override */
751 if (old_serial_count < MAX_LEGACY_SERIAL_PORTS) {
752 DBG("Moved legacy port %d -> %d\n", index,
753 old_serial_count);
754 serial_ports[old_serial_count++] =
755 serial_ports[index];
756 } else {
757 DBG("Replacing legacy port %d\n", index);
758 }
759 }
760 }
761 if (index >= MAX_LEGACY_SERIAL_PORTS)
762 goto next_port;
763 if (index >= old_serial_count)
764 old_serial_count = index + 1;
765
766 /* Now fill the entry */
767 memset(&serial_ports[index], 0, sizeof(struct plat_serial8250_port));
768 serial_ports[index].uartclk = clk ? *clk : BASE_BAUD * 16;
769 serial_ports[index].iobase = reg->address;
770 serial_ports[index].irq = interrupts ? interrupts[0] : 0;
771 serial_ports[index].flags = ASYNC_BOOT_AUTOCONF;
772
773 DBG("Added legacy port, index: %d, port: %x, irq: %d, clk: %d\n",
774 index,
775 serial_ports[index].iobase,
776 serial_ports[index].irq,
777 serial_ports[index].uartclk);
778
779 /* Get phys address of IO reg for port 1 */
780 if (index != 0)
781 goto next_port;
782
783 pci = of_get_parent(isa);
784 if (!pci) {
785 DBG("%s: no pci parent found\n", np->full_name);
786 goto next_port;
787 }
788
789 rangesp = (u32 *)get_property(pci, "ranges", &rlen);
790 if (rangesp == NULL) {
791 of_node_put(pci);
792 goto next_port;
793 }
794 rlen /= 4;
795
796 /* we need the #size-cells of the PCI bridge node itself */
797 phys_size = 1;
798 sizeprop = (u32 *)get_property(pci, "#size-cells", NULL);
799 if (sizeprop != NULL)
800 phys_size = *sizeprop;
801 /* we need the parent #addr-cells */
802 addr_size = prom_n_addr_cells(pci);
803 rentsize = 3 + addr_size + phys_size;
804 io_base = 0;
805 for (;rlen >= rentsize; rlen -= rentsize,rangesp += rentsize) {
806 if (((rangesp[0] >> 24) & 0x3) != 1)
807 continue; /* not IO space */
808 io_base = rangesp[3];
809 if (addr_size == 2)
810 io_base = (io_base << 32) | rangesp[4];
811 }
812 if (io_base != 0) {
813 *physport = io_base + reg->address;
814 if (default_speed && spd)
815 *default_speed = *spd;
816 }
817 of_node_put(pci);
818 next_port:
819 of_node_put(isa);
820 }
821
822 DBG(" <- generic_find_legacy_serial_port()\n");
823}
824
825static struct platform_device serial_device = {
826 .name = "serial8250",
827 .id = PLAT8250_DEV_PLATFORM,
828 .dev = {
829 .platform_data = serial_ports,
830 },
831};
832
833static int __init serial_dev_init(void)
834{
835 return platform_device_register(&serial_device);
836}
837arch_initcall(serial_dev_init);
838
839#endif /* CONFIG_PPC_ISERIES */
840
841int check_legacy_ioport(unsigned long base_port) 676int check_legacy_ioport(unsigned long base_port)
842{ 677{
843 if (ppc_md.check_legacy_ioport == NULL) 678 if (ppc_md.check_legacy_ioport == NULL)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 5a2eba60dd39..d3f0b6d452fb 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -76,7 +76,6 @@
76 * registers from *regs. This is what we need 76 * registers from *regs. This is what we need
77 * to do when a signal has been delivered. 77 * to do when a signal has been delivered.
78 */ 78 */
79#define sigreturn_exit(regs) return 0
80 79
81#define GP_REGS_SIZE min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32)) 80#define GP_REGS_SIZE min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32))
82#undef __SIGNAL_FRAMESIZE 81#undef __SIGNAL_FRAMESIZE
@@ -156,9 +155,17 @@ static inline int save_general_regs(struct pt_regs *regs,
156 elf_greg_t64 *gregs = (elf_greg_t64 *)regs; 155 elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
157 int i; 156 int i;
158 157
159 for (i = 0; i <= PT_RESULT; i ++) 158 if (!FULL_REGS(regs)) {
159 set_thread_flag(TIF_SAVE_NVGPRS);
160 current_thread_info()->nvgprs_frame = frame->mc_gregs;
161 }
162
163 for (i = 0; i <= PT_RESULT; i ++) {
164 if (i == 14 && !FULL_REGS(regs))
165 i = 32;
160 if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i])) 166 if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i]))
161 return -EFAULT; 167 return -EFAULT;
168 }
162 return 0; 169 return 0;
163} 170}
164 171
@@ -179,8 +186,6 @@ static inline int restore_general_regs(struct pt_regs *regs,
179 186
180#else /* CONFIG_PPC64 */ 187#else /* CONFIG_PPC64 */
181 188
182extern void sigreturn_exit(struct pt_regs *);
183
184#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) 189#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
185 190
186static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set) 191static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set)
@@ -214,6 +219,15 @@ static inline int get_old_sigaction(struct k_sigaction *new_ka,
214static inline int save_general_regs(struct pt_regs *regs, 219static inline int save_general_regs(struct pt_regs *regs,
215 struct mcontext __user *frame) 220 struct mcontext __user *frame)
216{ 221{
222 if (!FULL_REGS(regs)) {
223 /* Zero out the unsaved GPRs to avoid information
224 leak, and set TIF_SAVE_NVGPRS to ensure that the
225 registers do actually get saved later. */
226 memset(&regs->gpr[14], 0, 18 * sizeof(unsigned long));
227 current_thread_info()->nvgprs_frame = &frame->mc_gregs;
228 set_thread_flag(TIF_SAVE_NVGPRS);
229 }
230
217 return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE); 231 return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE);
218} 232}
219 233
@@ -256,8 +270,10 @@ long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
256 while (1) { 270 while (1) {
257 current->state = TASK_INTERRUPTIBLE; 271 current->state = TASK_INTERRUPTIBLE;
258 schedule(); 272 schedule();
259 if (do_signal(&saveset, regs)) 273 if (do_signal(&saveset, regs)) {
260 sigreturn_exit(regs); 274 set_thread_flag(TIF_RESTOREALL);
275 return 0;
276 }
261 } 277 }
262} 278}
263 279
@@ -292,8 +308,10 @@ long sys_rt_sigsuspend(
292 while (1) { 308 while (1) {
293 current->state = TASK_INTERRUPTIBLE; 309 current->state = TASK_INTERRUPTIBLE;
294 schedule(); 310 schedule();
295 if (do_signal(&saveset, regs)) 311 if (do_signal(&saveset, regs)) {
296 sigreturn_exit(regs); 312 set_thread_flag(TIF_RESTOREALL);
313 return 0;
314 }
297 } 315 }
298} 316}
299 317
@@ -391,9 +409,6 @@ struct rt_sigframe {
391static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, 409static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
392 int sigret) 410 int sigret)
393{ 411{
394#ifdef CONFIG_PPC32
395 CHECK_FULL_REGS(regs);
396#endif
397 /* Make sure floating point registers are stored in regs */ 412 /* Make sure floating point registers are stored in regs */
398 flush_fp_to_thread(current); 413 flush_fp_to_thread(current);
399 414
@@ -828,12 +843,6 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
828 regs->gpr[6] = (unsigned long) rt_sf; 843 regs->gpr[6] = (unsigned long) rt_sf;
829 regs->nip = (unsigned long) ka->sa.sa_handler; 844 regs->nip = (unsigned long) ka->sa.sa_handler;
830 regs->trap = 0; 845 regs->trap = 0;
831#ifdef CONFIG_PPC64
832 regs->result = 0;
833
834 if (test_thread_flag(TIF_SINGLESTEP))
835 ptrace_notify(SIGTRAP);
836#endif
837 return 1; 846 return 1;
838 847
839badframe: 848badframe:
@@ -911,8 +920,8 @@ long sys_swapcontext(struct ucontext __user *old_ctx,
911 */ 920 */
912 if (do_setcontext(new_ctx, regs, 0)) 921 if (do_setcontext(new_ctx, regs, 0))
913 do_exit(SIGSEGV); 922 do_exit(SIGSEGV);
914 sigreturn_exit(regs); 923
915 /* doesn't actually return back to here */ 924 set_thread_flag(TIF_RESTOREALL);
916 return 0; 925 return 0;
917} 926}
918 927
@@ -945,12 +954,11 @@ long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
945 * nobody does any... 954 * nobody does any...
946 */ 955 */
947 compat_sys_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs); 956 compat_sys_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs);
948 return (int)regs->result;
949#else 957#else
950 do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]); 958 do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]);
951 sigreturn_exit(regs); /* doesn't return here */
952 return 0;
953#endif 959#endif
960 set_thread_flag(TIF_RESTOREALL);
961 return 0;
954 962
955 bad: 963 bad:
956 force_sig(SIGSEGV, current); 964 force_sig(SIGSEGV, current);
@@ -1041,9 +1049,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
1041 */ 1049 */
1042 do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]); 1050 do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]);
1043 1051
1044 sigreturn_exit(regs); 1052 set_thread_flag(TIF_RESTOREALL);
1045 /* doesn't actually return back to here */
1046
1047 out: 1053 out:
1048 return 0; 1054 return 0;
1049} 1055}
@@ -1107,12 +1113,6 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
1107 regs->gpr[4] = (unsigned long) sc; 1113 regs->gpr[4] = (unsigned long) sc;
1108 regs->nip = (unsigned long) ka->sa.sa_handler; 1114 regs->nip = (unsigned long) ka->sa.sa_handler;
1109 regs->trap = 0; 1115 regs->trap = 0;
1110#ifdef CONFIG_PPC64
1111 regs->result = 0;
1112
1113 if (test_thread_flag(TIF_SINGLESTEP))
1114 ptrace_notify(SIGTRAP);
1115#endif
1116 1116
1117 return 1; 1117 return 1;
1118 1118
@@ -1160,12 +1160,8 @@ long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
1160 || restore_user_regs(regs, sr, 1)) 1160 || restore_user_regs(regs, sr, 1))
1161 goto badframe; 1161 goto badframe;
1162 1162
1163#ifdef CONFIG_PPC64 1163 set_thread_flag(TIF_RESTOREALL);
1164 return (int)regs->result;
1165#else
1166 sigreturn_exit(regs); /* doesn't return */
1167 return 0; 1164 return 0;
1168#endif
1169 1165
1170badframe: 1166badframe:
1171 force_sig(SIGSEGV, current); 1167 force_sig(SIGSEGV, current);
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 1decf2785530..5462bef898f6 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -96,8 +96,10 @@ long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, int p3, int
96 while (1) { 96 while (1) {
97 current->state = TASK_INTERRUPTIBLE; 97 current->state = TASK_INTERRUPTIBLE;
98 schedule(); 98 schedule();
99 if (do_signal(&saveset, regs)) 99 if (do_signal(&saveset, regs)) {
100 set_thread_flag(TIF_RESTOREALL);
100 return 0; 101 return 0;
102 }
101 } 103 }
102} 104}
103 105
@@ -152,6 +154,14 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
152 err |= __put_user(0, &sc->v_regs); 154 err |= __put_user(0, &sc->v_regs);
153#endif /* CONFIG_ALTIVEC */ 155#endif /* CONFIG_ALTIVEC */
154 err |= __put_user(&sc->gp_regs, &sc->regs); 156 err |= __put_user(&sc->gp_regs, &sc->regs);
157 if (!FULL_REGS(regs)) {
158 /* Zero out the unsaved GPRs to avoid information
159 leak, and set TIF_SAVE_NVGPRS to ensure that the
160 registers do actually get saved later. */
161 memset(&regs->gpr[14], 0, 18 * sizeof(unsigned long));
162 set_thread_flag(TIF_SAVE_NVGPRS);
163 current_thread_info()->nvgprs_frame = &sc->gp_regs;
164 }
155 err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE); 165 err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE);
156 err |= __copy_to_user(&sc->fp_regs, &current->thread.fpr, FP_REGS_SIZE); 166 err |= __copy_to_user(&sc->fp_regs, &current->thread.fpr, FP_REGS_SIZE);
157 err |= __put_user(signr, &sc->signal); 167 err |= __put_user(signr, &sc->signal);
@@ -340,6 +350,7 @@ int sys_swapcontext(struct ucontext __user *old_ctx,
340 do_exit(SIGSEGV); 350 do_exit(SIGSEGV);
341 351
342 /* This returns like rt_sigreturn */ 352 /* This returns like rt_sigreturn */
353 set_thread_flag(TIF_RESTOREALL);
343 return 0; 354 return 0;
344} 355}
345 356
@@ -372,7 +383,8 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
372 */ 383 */
373 do_sigaltstack(&uc->uc_stack, NULL, regs->gpr[1]); 384 do_sigaltstack(&uc->uc_stack, NULL, regs->gpr[1]);
374 385
375 return regs->result; 386 set_thread_flag(TIF_RESTOREALL);
387 return 0;
376 388
377badframe: 389badframe:
378#if DEBUG_SIG 390#if DEBUG_SIG
@@ -454,9 +466,6 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
454 if (err) 466 if (err)
455 goto badframe; 467 goto badframe;
456 468
457 if (test_thread_flag(TIF_SINGLESTEP))
458 ptrace_notify(SIGTRAP);
459
460 return 1; 469 return 1;
461 470
462badframe: 471badframe:
@@ -502,6 +511,8 @@ static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
502 * we only get here if there is a handler, we dont restart. 511 * we only get here if there is a handler, we dont restart.
503 */ 512 */
504 regs->result = -EINTR; 513 regs->result = -EINTR;
514 regs->gpr[3] = EINTR;
515 regs->ccr |= 0x10000000;
505 break; 516 break;
506 case -ERESTARTSYS: 517 case -ERESTARTSYS:
507 /* ERESTARTSYS means to restart the syscall if there is no 518 /* ERESTARTSYS means to restart the syscall if there is no
@@ -509,6 +520,8 @@ static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
509 */ 520 */
510 if (!(ka->sa.sa_flags & SA_RESTART)) { 521 if (!(ka->sa.sa_flags & SA_RESTART)) {
511 regs->result = -EINTR; 522 regs->result = -EINTR;
523 regs->gpr[3] = EINTR;
524 regs->ccr |= 0x10000000;
512 break; 525 break;
513 } 526 }
514 /* fallthrough */ 527 /* fallthrough */
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 30374d2f88e5..d381ec90b759 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -31,6 +31,7 @@
31#include <linux/sysdev.h> 31#include <linux/sysdev.h>
32#include <linux/cpu.h> 32#include <linux/cpu.h>
33#include <linux/notifier.h> 33#include <linux/notifier.h>
34#include <linux/topology.h>
34 35
35#include <asm/ptrace.h> 36#include <asm/ptrace.h>
36#include <asm/atomic.h> 37#include <asm/atomic.h>
@@ -75,6 +76,8 @@ void smp_call_function_interrupt(void);
75 76
76int smt_enabled_at_boot = 1; 77int smt_enabled_at_boot = 1;
77 78
79static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL;
80
78#ifdef CONFIG_MPIC 81#ifdef CONFIG_MPIC
79int __init smp_mpic_probe(void) 82int __init smp_mpic_probe(void)
80{ 83{
@@ -123,11 +126,16 @@ void smp_message_recv(int msg, struct pt_regs *regs)
123 /* XXX Do we have to do this? */ 126 /* XXX Do we have to do this? */
124 set_need_resched(); 127 set_need_resched();
125 break; 128 break;
126#ifdef CONFIG_DEBUGGER
127 case PPC_MSG_DEBUGGER_BREAK: 129 case PPC_MSG_DEBUGGER_BREAK:
130 if (crash_ipi_function_ptr) {
131 crash_ipi_function_ptr(regs);
132 break;
133 }
134#ifdef CONFIG_DEBUGGER
128 debugger_ipi(regs); 135 debugger_ipi(regs);
129 break; 136 break;
130#endif 137#endif /* CONFIG_DEBUGGER */
138 /* FALLTHROUGH */
131 default: 139 default:
132 printk("SMP %d: smp_message_recv(): unknown msg %d\n", 140 printk("SMP %d: smp_message_recv(): unknown msg %d\n",
133 smp_processor_id(), msg); 141 smp_processor_id(), msg);
@@ -147,6 +155,17 @@ void smp_send_debugger_break(int cpu)
147} 155}
148#endif 156#endif
149 157
158#ifdef CONFIG_KEXEC
159void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
160{
161 crash_ipi_function_ptr = crash_ipi_callback;
162 if (crash_ipi_callback) {
163 mb();
164 smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_DEBUGGER_BREAK);
165 }
166}
167#endif
168
150static void stop_this_cpu(void *dummy) 169static void stop_this_cpu(void *dummy)
151{ 170{
152 local_irq_disable(); 171 local_irq_disable();
@@ -452,10 +471,6 @@ int __devinit __cpu_up(unsigned int cpu)
452 if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)) 471 if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))
453 return -EINVAL; 472 return -EINVAL;
454 473
455#ifdef CONFIG_PPC64
456 paca[cpu].default_decr = tb_ticks_per_jiffy;
457#endif
458
459 /* Make sure callin-map entry is 0 (can be leftover a CPU 474 /* Make sure callin-map entry is 0 (can be leftover a CPU
460 * hotplug 475 * hotplug
461 */ 476 */
@@ -554,6 +569,8 @@ void __init smp_cpus_done(unsigned int max_cpus)
554 smp_ops->setup_cpu(boot_cpuid); 569 smp_ops->setup_cpu(boot_cpuid);
555 570
556 set_cpus_allowed(current, old_mask); 571 set_cpus_allowed(current, old_mask);
572
573 dump_numa_cpu_topology();
557} 574}
558 575
559#ifdef CONFIG_HOTPLUG_CPU 576#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index 91b93d917b64..ad895c99813b 100644
--- a/arch/powerpc/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -43,9 +43,6 @@
43#include <asm/time.h> 43#include <asm/time.h>
44#include <asm/unistd.h> 44#include <asm/unistd.h>
45 45
46extern unsigned long wall_jiffies;
47
48
49/* 46/*
50 * sys_ipc() is the de-multiplexer for the SysV IPC calls.. 47 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
51 * 48 *
@@ -311,31 +308,6 @@ int sys_olduname(struct oldold_utsname __user *name)
311 return error? -EFAULT: 0; 308 return error? -EFAULT: 0;
312} 309}
313 310
314#ifdef CONFIG_PPC64
315time_t sys64_time(time_t __user * tloc)
316{
317 time_t secs;
318 time_t usecs;
319
320 long tb_delta = tb_ticks_since(tb_last_stamp);
321 tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
322
323 secs = xtime.tv_sec;
324 usecs = (xtime.tv_nsec/1000) + tb_delta / tb_ticks_per_usec;
325 while (usecs >= USEC_PER_SEC) {
326 ++secs;
327 usecs -= USEC_PER_SEC;
328 }
329
330 if (tloc) {
331 if (put_user(secs,tloc))
332 secs = -EFAULT;
333 }
334
335 return secs;
336}
337#endif
338
339long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low, 311long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
340 u32 len_high, u32 len_low) 312 u32 len_high, u32 len_low)
341{ 313{
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
index 65eaea91b499..65463a1076e8 100644
--- a/arch/powerpc/kernel/systbl.S
+++ b/arch/powerpc/kernel/systbl.S
@@ -54,7 +54,7 @@ SYSCALL(link)
54SYSCALL(unlink) 54SYSCALL(unlink)
55COMPAT_SYS(execve) 55COMPAT_SYS(execve)
56SYSCALL(chdir) 56SYSCALL(chdir)
57SYSX(sys64_time,compat_sys_time,sys_time) 57COMPAT_SYS(time)
58SYSCALL(mknod) 58SYSCALL(mknod)
59SYSCALL(chmod) 59SYSCALL(chmod)
60SYSCALL(lchown) 60SYSCALL(lchown)
@@ -113,7 +113,7 @@ SYSCALL(sgetmask)
113COMPAT_SYS(ssetmask) 113COMPAT_SYS(ssetmask)
114SYSCALL(setreuid) 114SYSCALL(setreuid)
115SYSCALL(setregid) 115SYSCALL(setregid)
116SYSX(sys_ni_syscall,ppc32_sigsuspend,ppc_sigsuspend) 116SYS32ONLY(sigsuspend)
117COMPAT_SYS(sigpending) 117COMPAT_SYS(sigpending)
118COMPAT_SYS(sethostname) 118COMPAT_SYS(sethostname)
119COMPAT_SYS(setrlimit) 119COMPAT_SYS(setrlimit)
@@ -160,7 +160,7 @@ SYSCALL(swapoff)
160COMPAT_SYS(sysinfo) 160COMPAT_SYS(sysinfo)
161COMPAT_SYS(ipc) 161COMPAT_SYS(ipc)
162SYSCALL(fsync) 162SYSCALL(fsync)
163SYSX(sys_ni_syscall,ppc32_sigreturn,sys_sigreturn) 163SYS32ONLY(sigreturn)
164PPC_SYS(clone) 164PPC_SYS(clone)
165COMPAT_SYS(setdomainname) 165COMPAT_SYS(setdomainname)
166PPC_SYS(newuname) 166PPC_SYS(newuname)
@@ -213,13 +213,13 @@ COMPAT_SYS(nfsservctl)
213SYSCALL(setresgid) 213SYSCALL(setresgid)
214SYSCALL(getresgid) 214SYSCALL(getresgid)
215COMPAT_SYS(prctl) 215COMPAT_SYS(prctl)
216SYSX(ppc64_rt_sigreturn,ppc32_rt_sigreturn,sys_rt_sigreturn) 216COMPAT_SYS(rt_sigreturn)
217COMPAT_SYS(rt_sigaction) 217COMPAT_SYS(rt_sigaction)
218COMPAT_SYS(rt_sigprocmask) 218COMPAT_SYS(rt_sigprocmask)
219COMPAT_SYS(rt_sigpending) 219COMPAT_SYS(rt_sigpending)
220COMPAT_SYS(rt_sigtimedwait) 220COMPAT_SYS(rt_sigtimedwait)
221COMPAT_SYS(rt_sigqueueinfo) 221COMPAT_SYS(rt_sigqueueinfo)
222SYSX(ppc64_rt_sigsuspend,ppc32_rt_sigsuspend,ppc_rt_sigsuspend) 222COMPAT_SYS(rt_sigsuspend)
223COMPAT_SYS(pread64) 223COMPAT_SYS(pread64)
224COMPAT_SYS(pwrite64) 224COMPAT_SYS(pwrite64)
225SYSCALL(chown) 225SYSCALL(chown)
@@ -290,7 +290,7 @@ COMPAT_SYS(clock_settime)
290COMPAT_SYS(clock_gettime) 290COMPAT_SYS(clock_gettime)
291COMPAT_SYS(clock_getres) 291COMPAT_SYS(clock_getres)
292COMPAT_SYS(clock_nanosleep) 292COMPAT_SYS(clock_nanosleep)
293SYSX(ppc64_swapcontext,ppc32_swapcontext,ppc_swapcontext) 293COMPAT_SYS(swapcontext)
294COMPAT_SYS(tgkill) 294COMPAT_SYS(tgkill)
295COMPAT_SYS(utimes) 295COMPAT_SYS(utimes)
296COMPAT_SYS(statfs64) 296COMPAT_SYS(statfs64)
@@ -319,3 +319,5 @@ COMPAT_SYS(ioprio_get)
319SYSCALL(inotify_init) 319SYSCALL(inotify_init)
320SYSCALL(inotify_add_watch) 320SYSCALL(inotify_add_watch)
321SYSCALL(inotify_rm_watch) 321SYSCALL(inotify_rm_watch)
322SYSCALL(spu_run)
323SYSCALL(spu_create)
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index de8479769bb7..56f50e91bddb 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -699,10 +699,6 @@ void __init time_init(void)
699 div128_by_32(1024*1024, 0, tb_ticks_per_sec, &res); 699 div128_by_32(1024*1024, 0, tb_ticks_per_sec, &res);
700 tb_to_xs = res.result_low; 700 tb_to_xs = res.result_low;
701 701
702#ifdef CONFIG_PPC64
703 get_paca()->default_decr = tb_ticks_per_jiffy;
704#endif
705
706 /* 702 /*
707 * Compute scale factor for sched_clock. 703 * Compute scale factor for sched_clock.
708 * The calibrate_decr() function has set tb_ticks_per_sec, 704 * The calibrate_decr() function has set tb_ticks_per_sec,
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 1511454c4690..7509aa6474f2 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -31,6 +31,7 @@
31#include <linux/prctl.h> 31#include <linux/prctl.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/kprobes.h> 33#include <linux/kprobes.h>
34#include <linux/kexec.h>
34 35
35#include <asm/kdebug.h> 36#include <asm/kdebug.h>
36#include <asm/pgtable.h> 37#include <asm/pgtable.h>
@@ -95,7 +96,7 @@ static DEFINE_SPINLOCK(die_lock);
95 96
96int die(const char *str, struct pt_regs *regs, long err) 97int die(const char *str, struct pt_regs *regs, long err)
97{ 98{
98 static int die_counter; 99 static int die_counter, crash_dump_start = 0;
99 int nl = 0; 100 int nl = 0;
100 101
101 if (debugger(regs)) 102 if (debugger(regs))
@@ -156,7 +157,21 @@ int die(const char *str, struct pt_regs *regs, long err)
156 print_modules(); 157 print_modules();
157 show_regs(regs); 158 show_regs(regs);
158 bust_spinlocks(0); 159 bust_spinlocks(0);
160
161 if (!crash_dump_start && kexec_should_crash(current)) {
162 crash_dump_start = 1;
163 spin_unlock_irq(&die_lock);
164 crash_kexec(regs);
165 /* NOTREACHED */
166 }
159 spin_unlock_irq(&die_lock); 167 spin_unlock_irq(&die_lock);
168 if (crash_dump_start)
169 /*
170 * Only for soft-reset: Other CPUs will be responded to an IPI
171 * sent by first kexec CPU.
172 */
173 for(;;)
174 ;
160 175
161 if (in_interrupt()) 176 if (in_interrupt())
162 panic("Fatal exception in interrupt"); 177 panic("Fatal exception in interrupt");
@@ -215,8 +230,10 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
215void system_reset_exception(struct pt_regs *regs) 230void system_reset_exception(struct pt_regs *regs)
216{ 231{
217 /* See if any machine dependent calls */ 232 /* See if any machine dependent calls */
218 if (ppc_md.system_reset_exception) 233 if (ppc_md.system_reset_exception) {
219 ppc_md.system_reset_exception(regs); 234 if (ppc_md.system_reset_exception(regs))
235 return;
236 }
220 237
221 die("System Reset", regs, SIGABRT); 238 die("System Reset", regs, SIGABRT);
222 239
@@ -886,12 +903,10 @@ void altivec_unavailable_exception(struct pt_regs *regs)
886 die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); 903 die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
887} 904}
888 905
889#if defined(CONFIG_PPC64) || defined(CONFIG_E500)
890void performance_monitor_exception(struct pt_regs *regs) 906void performance_monitor_exception(struct pt_regs *regs)
891{ 907{
892 perf_irq(regs); 908 perf_irq(regs);
893} 909}
894#endif
895 910
896#ifdef CONFIG_8xx 911#ifdef CONFIG_8xx
897void SoftwareEmulation(struct pt_regs *regs) 912void SoftwareEmulation(struct pt_regs *regs)
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 0d878e72fc44..558c1ceb2b93 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -16,8 +16,8 @@
16#include <linux/console.h> 16#include <linux/console.h>
17#include <asm/processor.h> 17#include <asm/processor.h>
18 18
19void (*udbg_putc)(unsigned char c); 19void (*udbg_putc)(char c);
20unsigned char (*udbg_getc)(void); 20int (*udbg_getc)(void);
21int (*udbg_getc_poll)(void); 21int (*udbg_getc_poll)(void);
22 22
23/* udbg library, used by xmon et al */ 23/* udbg library, used by xmon et al */
@@ -57,8 +57,8 @@ int udbg_write(const char *s, int n)
57 57
58int udbg_read(char *buf, int buflen) 58int udbg_read(char *buf, int buflen)
59{ 59{
60 char c, *p = buf; 60 char *p = buf;
61 int i; 61 int i, c;
62 62
63 if (!udbg_getc) 63 if (!udbg_getc)
64 return 0; 64 return 0;
@@ -66,8 +66,11 @@ int udbg_read(char *buf, int buflen)
66 for (i = 0; i < buflen; ++i) { 66 for (i = 0; i < buflen; ++i) {
67 do { 67 do {
68 c = udbg_getc(); 68 c = udbg_getc();
69 if (c == -1 && i == 0)
70 return -1;
71
69 } while (c == 0x11 || c == 0x13); 72 } while (c == 0x11 || c == 0x13);
70 if (c == 0) 73 if (c == 0 || c == -1)
71 break; 74 break;
72 *p++ = c; 75 *p++ = c;
73 } 76 }
@@ -78,7 +81,7 @@ int udbg_read(char *buf, int buflen)
78#define UDBG_BUFSIZE 256 81#define UDBG_BUFSIZE 256
79void udbg_printf(const char *fmt, ...) 82void udbg_printf(const char *fmt, ...)
80{ 83{
81 unsigned char buf[UDBG_BUFSIZE]; 84 char buf[UDBG_BUFSIZE];
82 va_list args; 85 va_list args;
83 86
84 va_start(args, fmt); 87 va_start(args, fmt);
@@ -87,6 +90,12 @@ void udbg_printf(const char *fmt, ...)
87 va_end(args); 90 va_end(args);
88} 91}
89 92
93void __init udbg_progress(char *s, unsigned short hex)
94{
95 udbg_puts(s);
96 udbg_puts("\n");
97}
98
90/* 99/*
91 * Early boot console based on udbg 100 * Early boot console based on udbg
92 */ 101 */
@@ -99,7 +108,7 @@ static void udbg_console_write(struct console *con, const char *s,
99static struct console udbg_console = { 108static struct console udbg_console = {
100 .name = "udbg", 109 .name = "udbg",
101 .write = udbg_console_write, 110 .write = udbg_console_write,
102 .flags = CON_PRINTBUFFER, 111 .flags = CON_PRINTBUFFER | CON_ENABLED,
103 .index = -1, 112 .index = -1,
104}; 113};
105 114
@@ -107,15 +116,19 @@ static int early_console_initialized;
107 116
108void __init disable_early_printk(void) 117void __init disable_early_printk(void)
109{ 118{
119#if 1
110 if (!early_console_initialized) 120 if (!early_console_initialized)
111 return; 121 return;
112 unregister_console(&udbg_console); 122 unregister_console(&udbg_console);
113 early_console_initialized = 0; 123 early_console_initialized = 0;
124#endif
114} 125}
115 126
116/* called by setup_system */ 127/* called by setup_system */
117void register_early_udbg_console(void) 128void register_early_udbg_console(void)
118{ 129{
130 if (early_console_initialized)
131 return;
119 early_console_initialized = 1; 132 early_console_initialized = 1;
120 register_console(&udbg_console); 133 register_console(&udbg_console);
121} 134}
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c
index 9313574ab935..7541bf44d2da 100644
--- a/arch/powerpc/kernel/udbg_16550.c
+++ b/arch/powerpc/kernel/udbg_16550.c
@@ -43,9 +43,11 @@ struct NS16550 {
43#define LSR_TEMT 0x40 /* Xmitter empty */ 43#define LSR_TEMT 0x40 /* Xmitter empty */
44#define LSR_ERR 0x80 /* Error */ 44#define LSR_ERR 0x80 /* Error */
45 45
46#define LCR_DLAB 0x80
47
46static volatile struct NS16550 __iomem *udbg_comport; 48static volatile struct NS16550 __iomem *udbg_comport;
47 49
48static void udbg_550_putc(unsigned char c) 50static void udbg_550_putc(char c)
49{ 51{
50 if (udbg_comport) { 52 if (udbg_comport) {
51 while ((in_8(&udbg_comport->lsr) & LSR_THRE) == 0) 53 while ((in_8(&udbg_comport->lsr) & LSR_THRE) == 0)
@@ -67,39 +69,80 @@ static int udbg_550_getc_poll(void)
67 return -1; 69 return -1;
68} 70}
69 71
70static unsigned char udbg_550_getc(void) 72static int udbg_550_getc(void)
71{ 73{
72 if (udbg_comport) { 74 if (udbg_comport) {
73 while ((in_8(&udbg_comport->lsr) & LSR_DR) == 0) 75 while ((in_8(&udbg_comport->lsr) & LSR_DR) == 0)
74 /* wait for char */; 76 /* wait for char */;
75 return in_8(&udbg_comport->rbr); 77 return in_8(&udbg_comport->rbr);
76 } 78 }
77 return 0; 79 return -1;
78} 80}
79 81
80void udbg_init_uart(void __iomem *comport, unsigned int speed) 82void udbg_init_uart(void __iomem *comport, unsigned int speed,
83 unsigned int clock)
81{ 84{
82 u16 dll = speed ? (115200 / speed) : 12; 85 unsigned int dll, base_bauds = clock / 16;
86
87 if (speed == 0)
88 speed = 9600;
89 dll = base_bauds / speed;
83 90
84 if (comport) { 91 if (comport) {
85 udbg_comport = (struct NS16550 __iomem *)comport; 92 udbg_comport = (struct NS16550 __iomem *)comport;
86 out_8(&udbg_comport->lcr, 0x00); 93 out_8(&udbg_comport->lcr, 0x00);
87 out_8(&udbg_comport->ier, 0xff); 94 out_8(&udbg_comport->ier, 0xff);
88 out_8(&udbg_comport->ier, 0x00); 95 out_8(&udbg_comport->ier, 0x00);
89 out_8(&udbg_comport->lcr, 0x80); /* Access baud rate */ 96 out_8(&udbg_comport->lcr, LCR_DLAB);
90 out_8(&udbg_comport->dll, dll & 0xff); /* 1 = 115200, 2 = 57600, 97 out_8(&udbg_comport->dll, dll & 0xff);
91 3 = 38400, 12 = 9600 baud */ 98 out_8(&udbg_comport->dlm, dll >> 8);
92 out_8(&udbg_comport->dlm, dll >> 8); /* dll >> 8 which should be zero 99 /* 8 data, 1 stop, no parity */
93 for fast rates; */ 100 out_8(&udbg_comport->lcr, 0x03);
94 out_8(&udbg_comport->lcr, 0x03); /* 8 data, 1 stop, no parity */ 101 /* RTS/DTR */
95 out_8(&udbg_comport->mcr, 0x03); /* RTS/DTR */ 102 out_8(&udbg_comport->mcr, 0x03);
96 out_8(&udbg_comport->fcr ,0x07); /* Clear & enable FIFOs */ 103 /* Clear & enable FIFOs */
104 out_8(&udbg_comport->fcr ,0x07);
97 udbg_putc = udbg_550_putc; 105 udbg_putc = udbg_550_putc;
98 udbg_getc = udbg_550_getc; 106 udbg_getc = udbg_550_getc;
99 udbg_getc_poll = udbg_550_getc_poll; 107 udbg_getc_poll = udbg_550_getc_poll;
100 } 108 }
101} 109}
102 110
111unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock)
112{
113 unsigned int dll, dlm, divisor, prescaler, speed;
114 u8 old_lcr;
115 volatile struct NS16550 __iomem *port = comport;
116
117 old_lcr = in_8(&port->lcr);
118
119 /* select divisor latch registers. */
120 out_8(&port->lcr, LCR_DLAB);
121
122 /* now, read the divisor */
123 dll = in_8(&port->dll);
124 dlm = in_8(&port->dlm);
125 divisor = dlm << 8 | dll;
126
127 /* check prescaling */
128 if (in_8(&port->mcr) & 0x80)
129 prescaler = 4;
130 else
131 prescaler = 1;
132
133 /* restore the LCR */
134 out_8(&port->lcr, old_lcr);
135
136 /* calculate speed */
137 speed = (clock / prescaler) / (divisor * 16);
138
139 /* sanity check */
140 if (speed < 0 || speed > (clock / 16))
141 speed = 9600;
142
143 return speed;
144}
145
103#ifdef CONFIG_PPC_MAPLE 146#ifdef CONFIG_PPC_MAPLE
104void udbg_maple_real_putc(unsigned char c) 147void udbg_maple_real_putc(unsigned char c)
105{ 148{
diff --git a/arch/powerpc/kernel/udbg_scc.c b/arch/powerpc/kernel/udbg_scc.c
deleted file mode 100644
index 820c53551507..000000000000
--- a/arch/powerpc/kernel/udbg_scc.c
+++ /dev/null
@@ -1,135 +0,0 @@
1/*
2 * udbg for for zilog scc ports as found on Apple PowerMacs
3 *
4 * Copyright (C) 2001-2005 PPC 64 Team, IBM Corp
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11#include <linux/config.h>
12#include <linux/types.h>
13#include <asm/udbg.h>
14#include <asm/processor.h>
15#include <asm/io.h>
16#include <asm/prom.h>
17#include <asm/pmac_feature.h>
18
19extern u8 real_readb(volatile u8 __iomem *addr);
20extern void real_writeb(u8 data, volatile u8 __iomem *addr);
21
22#define SCC_TXRDY 4
23#define SCC_RXRDY 1
24
25static volatile u8 __iomem *sccc;
26static volatile u8 __iomem *sccd;
27
28static void udbg_scc_putc(unsigned char c)
29{
30 if (sccc) {
31 while ((in_8(sccc) & SCC_TXRDY) == 0)
32 ;
33 out_8(sccd, c);
34 if (c == '\n')
35 udbg_scc_putc('\r');
36 }
37}
38
39static int udbg_scc_getc_poll(void)
40{
41 if (sccc) {
42 if ((in_8(sccc) & SCC_RXRDY) != 0)
43 return in_8(sccd);
44 else
45 return -1;
46 }
47 return -1;
48}
49
50static unsigned char udbg_scc_getc(void)
51{
52 if (sccc) {
53 while ((in_8(sccc) & SCC_RXRDY) == 0)
54 ;
55 return in_8(sccd);
56 }
57 return 0;
58}
59
60static unsigned char scc_inittab[] = {
61 13, 0, /* set baud rate divisor */
62 12, 0,
63 14, 1, /* baud rate gen enable, src=rtxc */
64 11, 0x50, /* clocks = br gen */
65 5, 0xea, /* tx 8 bits, assert DTR & RTS */
66 4, 0x46, /* x16 clock, 1 stop */
67 3, 0xc1, /* rx enable, 8 bits */
68};
69
70void udbg_init_scc(struct device_node *np)
71{
72 u32 *reg;
73 unsigned long addr;
74 int i, x;
75
76 if (np == NULL)
77 np = of_find_node_by_name(NULL, "escc");
78 if (np == NULL || np->parent == NULL)
79 return;
80
81 udbg_printf("found SCC...\n");
82 /* Get address within mac-io ASIC */
83 reg = (u32 *)get_property(np, "reg", NULL);
84 if (reg == NULL)
85 return;
86 addr = reg[0];
87 udbg_printf("local addr: %lx\n", addr);
88 /* Get address of mac-io PCI itself */
89 reg = (u32 *)get_property(np->parent, "assigned-addresses", NULL);
90 if (reg == NULL)
91 return;
92 addr += reg[2];
93 udbg_printf("final addr: %lx\n", addr);
94
95 /* Setup for 57600 8N1 */
96 addr += 0x20;
97 sccc = (volatile u8 * __iomem) ioremap(addr & PAGE_MASK, PAGE_SIZE) ;
98 sccc += addr & ~PAGE_MASK;
99 sccd = sccc + 0x10;
100
101 udbg_printf("ioremap result sccc: %p\n", sccc);
102 mb();
103
104 for (i = 20000; i != 0; --i)
105 x = in_8(sccc);
106 out_8(sccc, 0x09); /* reset A or B side */
107 out_8(sccc, 0xc0);
108 for (i = 0; i < sizeof(scc_inittab); ++i)
109 out_8(sccc, scc_inittab[i]);
110
111 udbg_putc = udbg_scc_putc;
112 udbg_getc = udbg_scc_getc;
113 udbg_getc_poll = udbg_scc_getc_poll;
114
115 udbg_puts("Hello World !\n");
116}
117
118static void udbg_real_scc_putc(unsigned char c)
119{
120 while ((real_readb(sccc) & SCC_TXRDY) == 0)
121 ;
122 real_writeb(c, sccd);
123 if (c == '\n')
124 udbg_real_scc_putc('\r');
125}
126
127void udbg_init_pmac_realmode(void)
128{
129 sccc = (volatile u8 __iomem *)0x80013020ul;
130 sccd = (volatile u8 __iomem *)0x80013030ul;
131
132 udbg_putc = udbg_real_scc_putc;
133 udbg_getc = NULL;
134 udbg_getc_poll = NULL;
135}