aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-10-05 22:06:20 -0400
committerPaul Mackerras <paulus@samba.org>2005-10-05 22:06:20 -0400
commit9b6b563c0d2d25ecc3111916031aa7255543fbfb (patch)
tree07fd029308055461caa157d15a88c01861efc6bb /arch/powerpc
parentb85a046af3a260e079505e8023ccd10e01cf4f2b (diff)
powerpc: Merge in the ppc64 version of the prom code.
This brings in the ppc64 version of prom_init.c, prom.c and btext.c and makes them work for ppc32. This also brings in the new calling convention, where the first entry to the kernel (with r5 != 0) goes to the prom_init code, which then restarts from the beginning (with r5 == 0) after it has done its stuff. For now this also brings in the ppc32 version of setup.c. It also merges lmb.h. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/kernel/Makefile11
-rw-r--r--arch/powerpc/kernel/btext.c852
-rw-r--r--arch/powerpc/kernel/head.S16
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c30
-rw-r--r--arch/powerpc/kernel/prom.c2141
-rw-r--r--arch/powerpc/kernel/prom_init.c2126
-rw-r--r--arch/powerpc/kernel/setup.c678
-rw-r--r--arch/powerpc/platforms/powermac/pmac_setup.c11
8 files changed, 5817 insertions, 48 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index be3f9d123a6d..4842e82dbc2b 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -5,10 +5,11 @@
5ifeq ($(CONFIG_PPC64),y) 5ifeq ($(CONFIG_PPC64),y)
6EXTRA_CFLAGS += -mno-minimal-toc 6EXTRA_CFLAGS += -mno-minimal-toc
7endif 7endif
8
9ifeq ($(CONFIG_PPC32),y) 8ifeq ($(CONFIG_PPC32),y)
10extra-$(CONFIG_PPC_STD_MMU) := head.o 9CFLAGS_prom_init.o += -fPIC
11endif 10endif
11
12extra-$(CONFIG_PPC_STD_MMU) := head.o
12extra-$(CONFIG_PPC64) := head_64.o 13extra-$(CONFIG_PPC64) := head_64.o
13extra-$(CONFIG_40x) := head_4xx.o 14extra-$(CONFIG_40x) := head_4xx.o
14extra-$(CONFIG_44x) := head_44x.o 15extra-$(CONFIG_44x) := head_44x.o
@@ -18,13 +19,15 @@ extra-$(CONFIG_6xx) += idle_6xx.o
18extra-$(CONFIG_PPC_FPU) += fpu.o 19extra-$(CONFIG_PPC_FPU) += fpu.o
19extra-y += vmlinux.lds 20extra-y += vmlinux.lds
20 21
21obj-y := traps.o 22obj-y := traps.o prom.o semaphore.o
22obj-$(CONFIG_PPC32) += semaphore.o process.o 23obj-$(CONFIG_PPC32) += setup.o process.o
23obj-$(CONFIG_PPC64) += idle_power4.o 24obj-$(CONFIG_PPC64) += idle_power4.o
24ifeq ($(CONFIG_PPC32),y) 25ifeq ($(CONFIG_PPC32),y)
26obj-$(CONFIG_PPC_OF) += prom_init.o
25obj-$(CONFIG_MODULES) += ppc_ksyms.o 27obj-$(CONFIG_MODULES) += ppc_ksyms.o
26endif 28endif
27obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o 29obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
30obj-$(CONFIG_BOOTX_TEXT) += btext.o
28 31
29ifeq ($(CONFIG_PPC_ISERIES),y) 32ifeq ($(CONFIG_PPC_ISERIES),y)
30arch/powerpc/kernel/head_64.o: arch/powerpc/platforms/iseries/lparmap.s 33arch/powerpc/kernel/head_64.o: arch/powerpc/platforms/iseries/lparmap.s
diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c
new file mode 100644
index 000000000000..44f5d98e27c0
--- /dev/null
+++ b/arch/powerpc/kernel/btext.c
@@ -0,0 +1,852 @@
1/*
2 * Procedures for drawing on the screen early on in the boot process.
3 *
4 * Benjamin Herrenschmidt <benh@kernel.crashing.org>
5 */
6#include <linux/config.h>
7#include <linux/kernel.h>
8#include <linux/string.h>
9#include <linux/init.h>
10#include <linux/module.h>
11
12#include <asm/sections.h>
13#include <asm/prom.h>
14#include <asm/btext.h>
15#include <asm/prom.h>
16#include <asm/page.h>
17#include <asm/mmu.h>
18#include <asm/pgtable.h>
19#include <asm/io.h>
20#include <asm/lmb.h>
21#include <asm/processor.h>
22
23#define NO_SCROLL
24
25#ifndef NO_SCROLL
26static void scrollscreen(void);
27#endif
28
29static void draw_byte(unsigned char c, long locX, long locY);
30static 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);
32static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb);
33
34static int g_loc_X;
35static int g_loc_Y;
36static int g_max_loc_X;
37static int g_max_loc_Y;
38
39static int dispDeviceRowBytes;
40static int dispDeviceDepth;
41static int dispDeviceRect[4];
42static unsigned char *dispDeviceBase, *logicalDisplayBase;
43
44unsigned long disp_BAT[2] __initdata = {0, 0};
45
46#define cmapsz (16*256)
47
48static unsigned char vga_font[cmapsz];
49
50int boot_text_mapped;
51int force_printk_to_btext = 0;
52
53
54/* Calc BAT values for mapping the display and store them
55 * in disp_BAT. Those values are then used from head.S to map
56 * the display during identify_machine() and MMU_Init()
57 *
58 * The display is mapped to virtual address 0xD0000000, rather
59 * than 1:1, because some some CHRP machines put the frame buffer
60 * in the region starting at 0xC0000000 (KERNELBASE).
61 * This mapping is temporary and will disappear as soon as the
62 * setup done by MMU_Init() is applied.
63 *
64 * For now, we align the BAT and then map 8Mb on 601 and 16Mb
65 * on other PPCs. This may cause trouble if the framebuffer
66 * is really badly aligned, but I didn't encounter this case
67 * yet.
68 */
69void __init
70btext_prepare_BAT(void)
71{
72 unsigned long vaddr = KERNELBASE + 0x10000000;
73 unsigned long addr;
74 unsigned long lowbits;
75
76 addr = (unsigned long)dispDeviceBase;
77 if (!addr) {
78 boot_text_mapped = 0;
79 return;
80 }
81 if (PVR_VER(mfspr(SPRN_PVR)) != 1) {
82 /* 603, 604, G3, G4, ... */
83 lowbits = addr & ~0xFF000000UL;
84 addr &= 0xFF000000UL;
85 disp_BAT[0] = vaddr | (BL_16M<<2) | 2;
86 disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);
87 } else {
88 /* 601 */
89 lowbits = addr & ~0xFF800000UL;
90 addr &= 0xFF800000UL;
91 disp_BAT[0] = vaddr | (_PAGE_NO_CACHE | PP_RWXX) | 4;
92 disp_BAT[1] = addr | BL_8M | 0x40;
93 }
94 logicalDisplayBase = (void *) (vaddr + lowbits);
95}
96
97/* This function will enable the early boot text when doing OF booting. This
98 * way, xmon output should work too
99 */
100void __init
101btext_setup_display(int width, int height, int depth, int pitch,
102 unsigned long address)
103{
104 g_loc_X = 0;
105 g_loc_Y = 0;
106 g_max_loc_X = width / 8;
107 g_max_loc_Y = height / 16;
108 logicalDisplayBase = (unsigned char *)address;
109 dispDeviceBase = (unsigned char *)address;
110 dispDeviceRowBytes = pitch;
111 dispDeviceDepth = depth;
112 dispDeviceRect[0] = dispDeviceRect[1] = 0;
113 dispDeviceRect[2] = width;
114 dispDeviceRect[3] = height;
115 boot_text_mapped = 1;
116}
117
118/* Here's a small text engine to use during early boot
119 * or for debugging purposes
120 *
121 * todo:
122 *
123 * - build some kind of vgacon with it to enable early printk
124 * - move to a separate file
125 * - add a few video driver hooks to keep in sync with display
126 * changes.
127 */
128
129void map_boot_text(void)
130{
131 unsigned long base, offset, size;
132 unsigned char *vbase;
133
134 /* By default, we are no longer mapped */
135 boot_text_mapped = 0;
136 if (dispDeviceBase == 0)
137 return;
138 base = ((unsigned long) dispDeviceBase) & 0xFFFFF000UL;
139 offset = ((unsigned long) dispDeviceBase) - base;
140 size = dispDeviceRowBytes * dispDeviceRect[3] + offset
141 + dispDeviceRect[0];
142 vbase = __ioremap(base, size, _PAGE_NO_CACHE);
143 if (vbase == 0)
144 return;
145 logicalDisplayBase = vbase + offset;
146 boot_text_mapped = 1;
147}
148
149int btext_initialize(struct device_node *np)
150{
151 unsigned int width, height, depth, pitch;
152 unsigned long address = 0;
153 u32 *prop;
154
155 prop = (u32 *)get_property(np, "width", NULL);
156 if (prop == NULL)
157 return -EINVAL;
158 width = *prop;
159 prop = (u32 *)get_property(np, "height", NULL);
160 if (prop == NULL)
161 return -EINVAL;
162 height = *prop;
163 prop = (u32 *)get_property(np, "depth", NULL);
164 if (prop == NULL)
165 return -EINVAL;
166 depth = *prop;
167 pitch = width * ((depth + 7) / 8);
168 prop = (u32 *)get_property(np, "linebytes", NULL);
169 if (prop)
170 pitch = *prop;
171 if (pitch == 1)
172 pitch = 0x1000;
173 prop = (u32 *)get_property(np, "address", NULL);
174 if (prop)
175 address = *prop;
176
177 /* FIXME: Add support for PCI reg properties */
178
179 if (address == 0)
180 return -EINVAL;
181
182 g_loc_X = 0;
183 g_loc_Y = 0;
184 g_max_loc_X = width / 8;
185 g_max_loc_Y = height / 16;
186 logicalDisplayBase = (unsigned char *)address;
187 dispDeviceBase = (unsigned char *)address;
188 dispDeviceRowBytes = pitch;
189 dispDeviceDepth = depth;
190 dispDeviceRect[0] = dispDeviceRect[1] = 0;
191 dispDeviceRect[2] = width;
192 dispDeviceRect[3] = height;
193
194 map_boot_text();
195
196 return 0;
197}
198
199void __init init_boot_display(void)
200{
201 char *name;
202 struct device_node *np = NULL;
203 int rc = -ENODEV;
204
205 printk("trying to initialize btext ...\n");
206
207 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
208 if (name != NULL) {
209 np = of_find_node_by_path(name);
210 if (np != NULL) {
211 if (strcmp(np->type, "display") != 0) {
212 printk("boot stdout isn't a display !\n");
213 of_node_put(np);
214 np = NULL;
215 }
216 }
217 }
218 if (np)
219 rc = btext_initialize(np);
220 if (rc == 0)
221 return;
222
223 for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
224 if (get_property(np, "linux,opened", NULL)) {
225 printk("trying %s ...\n", np->full_name);
226 rc = btext_initialize(np);
227 printk("result: %d\n", rc);
228 }
229 if (rc == 0)
230 return;
231 }
232}
233
234/* Calc the base address of a given point (x,y) */
235static unsigned char * calc_base(int x, int y)
236{
237 unsigned char *base;
238
239 base = logicalDisplayBase;
240 if (base == 0)
241 base = dispDeviceBase;
242 base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3);
243 base += (y + dispDeviceRect[1]) * dispDeviceRowBytes;
244 return base;
245}
246
247/* Adjust the display to a new resolution */
248void btext_update_display(unsigned long phys, int width, int height,
249 int depth, int pitch)
250{
251 if (dispDeviceBase == 0)
252 return;
253
254 /* check it's the same frame buffer (within 256MB) */
255 if ((phys ^ (unsigned long)dispDeviceBase) & 0xf0000000)
256 return;
257
258 dispDeviceBase = (__u8 *) phys;
259 dispDeviceRect[0] = 0;
260 dispDeviceRect[1] = 0;
261 dispDeviceRect[2] = width;
262 dispDeviceRect[3] = height;
263 dispDeviceDepth = depth;
264 dispDeviceRowBytes = pitch;
265 if (boot_text_mapped) {
266 iounmap(logicalDisplayBase);
267 boot_text_mapped = 0;
268 }
269 map_boot_text();
270 g_loc_X = 0;
271 g_loc_Y = 0;
272 g_max_loc_X = width / 8;
273 g_max_loc_Y = height / 16;
274}
275EXPORT_SYMBOL(btext_update_display);
276
277void btext_clearscreen(void)
278{
279 unsigned long *base = (unsigned long *)calc_base(0, 0);
280 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
281 (dispDeviceDepth >> 3)) >> 3;
282 int i,j;
283
284 for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
285 {
286 unsigned long *ptr = base;
287 for(j=width; j; --j)
288 *(ptr++) = 0;
289 base += (dispDeviceRowBytes >> 3);
290 }
291}
292
293#ifndef NO_SCROLL
294static void scrollscreen(void)
295{
296 unsigned long *src = (unsigned long *)calc_base(0,16);
297 unsigned long *dst = (unsigned long *)calc_base(0,0);
298 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
299 (dispDeviceDepth >> 3)) >> 3;
300 int i,j;
301
302 for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
303 {
304 unsigned long *src_ptr = src;
305 unsigned long *dst_ptr = dst;
306 for(j=width; j; --j)
307 *(dst_ptr++) = *(src_ptr++);
308 src += (dispDeviceRowBytes >> 3);
309 dst += (dispDeviceRowBytes >> 3);
310 }
311 for (i=0; i<16; i++)
312 {
313 unsigned long *dst_ptr = dst;
314 for(j=width; j; --j)
315 *(dst_ptr++) = 0;
316 dst += (dispDeviceRowBytes >> 3);
317 }
318}
319#endif /* ndef NO_SCROLL */
320
321void btext_drawchar(char c)
322{
323 int cline = 0;
324#ifdef NO_SCROLL
325 int x;
326#endif
327 if (!boot_text_mapped)
328 return;
329
330 switch (c) {
331 case '\b':
332 if (g_loc_X > 0)
333 --g_loc_X;
334 break;
335 case '\t':
336 g_loc_X = (g_loc_X & -8) + 8;
337 break;
338 case '\r':
339 g_loc_X = 0;
340 break;
341 case '\n':
342 g_loc_X = 0;
343 g_loc_Y++;
344 cline = 1;
345 break;
346 default:
347 draw_byte(c, g_loc_X++, g_loc_Y);
348 }
349 if (g_loc_X >= g_max_loc_X) {
350 g_loc_X = 0;
351 g_loc_Y++;
352 cline = 1;
353 }
354#ifndef NO_SCROLL
355 while (g_loc_Y >= g_max_loc_Y) {
356 scrollscreen();
357 g_loc_Y--;
358 }
359#else
360 /* wrap around from bottom to top of screen so we don't
361 waste time scrolling each line. -- paulus. */
362 if (g_loc_Y >= g_max_loc_Y)
363 g_loc_Y = 0;
364 if (cline) {
365 for (x = 0; x < g_max_loc_X; ++x)
366 draw_byte(' ', x, g_loc_Y);
367 }
368#endif
369}
370
371void btext_drawstring(const char *c)
372{
373 if (!boot_text_mapped)
374 return;
375 while (*c)
376 btext_drawchar(*c++);
377}
378
379void btext_drawhex(unsigned long v)
380{
381 char *hex_table = "0123456789abcdef";
382
383 if (!boot_text_mapped)
384 return;
385#ifdef CONFIG_PPC64
386 btext_drawchar(hex_table[(v >> 60) & 0x0000000FUL]);
387 btext_drawchar(hex_table[(v >> 56) & 0x0000000FUL]);
388 btext_drawchar(hex_table[(v >> 52) & 0x0000000FUL]);
389 btext_drawchar(hex_table[(v >> 48) & 0x0000000FUL]);
390 btext_drawchar(hex_table[(v >> 44) & 0x0000000FUL]);
391 btext_drawchar(hex_table[(v >> 40) & 0x0000000FUL]);
392 btext_drawchar(hex_table[(v >> 36) & 0x0000000FUL]);
393 btext_drawchar(hex_table[(v >> 32) & 0x0000000FUL]);
394#endif
395 btext_drawchar(hex_table[(v >> 28) & 0x0000000FUL]);
396 btext_drawchar(hex_table[(v >> 24) & 0x0000000FUL]);
397 btext_drawchar(hex_table[(v >> 20) & 0x0000000FUL]);
398 btext_drawchar(hex_table[(v >> 16) & 0x0000000FUL]);
399 btext_drawchar(hex_table[(v >> 12) & 0x0000000FUL]);
400 btext_drawchar(hex_table[(v >> 8) & 0x0000000FUL]);
401 btext_drawchar(hex_table[(v >> 4) & 0x0000000FUL]);
402 btext_drawchar(hex_table[(v >> 0) & 0x0000000FUL]);
403 btext_drawchar(' ');
404}
405
406static void draw_byte(unsigned char c, long locX, long locY)
407{
408 unsigned char *base = calc_base(locX << 3, locY << 4);
409 unsigned char *font = &vga_font[((unsigned int)c) * 16];
410 int rb = dispDeviceRowBytes;
411
412 switch(dispDeviceDepth) {
413 case 24:
414 case 32:
415 draw_byte_32(font, (unsigned int *)base, rb);
416 break;
417 case 15:
418 case 16:
419 draw_byte_16(font, (unsigned int *)base, rb);
420 break;
421 case 8:
422 draw_byte_8(font, (unsigned int *)base, rb);
423 break;
424 }
425}
426
427static unsigned int expand_bits_8[16] = {
428 0x00000000,
429 0x000000ff,
430 0x0000ff00,
431 0x0000ffff,
432 0x00ff0000,
433 0x00ff00ff,
434 0x00ffff00,
435 0x00ffffff,
436 0xff000000,
437 0xff0000ff,
438 0xff00ff00,
439 0xff00ffff,
440 0xffff0000,
441 0xffff00ff,
442 0xffffff00,
443 0xffffffff
444};
445
446static unsigned int expand_bits_16[4] = {
447 0x00000000,
448 0x0000ffff,
449 0xffff0000,
450 0xffffffff
451};
452
453
454static void draw_byte_32(unsigned char *font, unsigned int *base, int rb)
455{
456 int l, bits;
457 int fg = 0xFFFFFFFFUL;
458 int bg = 0x00000000UL;
459
460 for (l = 0; l < 16; ++l)
461 {
462 bits = *font++;
463 base[0] = (-(bits >> 7) & fg) ^ bg;
464 base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
465 base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
466 base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
467 base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
468 base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
469 base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
470 base[7] = (-(bits & 1) & fg) ^ bg;
471 base = (unsigned int *) ((char *)base + rb);
472 }
473}
474
475static void draw_byte_16(unsigned char *font, unsigned int *base, int rb)
476{
477 int l, bits;
478 int fg = 0xFFFFFFFFUL;
479 int bg = 0x00000000UL;
480 unsigned int *eb = (int *)expand_bits_16;
481
482 for (l = 0; l < 16; ++l)
483 {
484 bits = *font++;
485 base[0] = (eb[bits >> 6] & fg) ^ bg;
486 base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
487 base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
488 base[3] = (eb[bits & 3] & fg) ^ bg;
489 base = (unsigned int *) ((char *)base + rb);
490 }
491}
492
493static void draw_byte_8(unsigned char *font, unsigned int *base, int rb)
494{
495 int l, bits;
496 int fg = 0x0F0F0F0FUL;
497 int bg = 0x00000000UL;
498 unsigned int *eb = (int *)expand_bits_8;
499
500 for (l = 0; l < 16; ++l)
501 {
502 bits = *font++;
503 base[0] = (eb[bits >> 4] & fg) ^ bg;
504 base[1] = (eb[bits & 0xf] & fg) ^ bg;
505 base = (unsigned int *) ((char *)base + rb);
506 }
507}
508
509static unsigned char vga_font[cmapsz] = {
5100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd,
5120x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff,
5130xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
5140x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10,
5150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
5160x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
5170x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
5180x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c,
5190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
5200x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
5210xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
5220x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
5230x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
5240xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e,
5250x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
5260x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18,
5270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30,
5280x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63,
5290x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
5300x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18,
5310x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8,
5320xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e,
5330x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
5340x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
5350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
5360x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb,
5370xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
5380x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6,
5390x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5400xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
5410x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
5420x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
5430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
5440x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5450x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5460x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
5470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
5480xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5490x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5500x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00,
5510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c,
5520x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5540x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
5550x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
5560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
5570x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
5580x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c,
5590x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18,
5600x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
5610x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
5620x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
5640x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
5650x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
5660x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
5670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
5680x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5690x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
5700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
5710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5720x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5730x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
5740x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c,
5750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
5760x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
5770x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
5780x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c,
5790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe,
5800x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
5810xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
5820x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
5830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18,
5840x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
5850xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
5860x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
5870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
5880x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5890x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
5900x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06,
5910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
5920x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
5930x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
5940x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
5950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde,
5960xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
5970x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
5980x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc,
5990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0,
6000xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c,
6010x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
6020x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe,
6030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68,
6040x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
6050xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
6060x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
6070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
6080x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
6090x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
6100x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6,
6110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
6120x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7,
6130xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
6140x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6,
6150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
6160xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66,
6170x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
6180x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c,
6190x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c,
6200x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
6210xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
6220x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
6230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
6240xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
6250xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
6260x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66,
6270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18,
6280x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
6290xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
6300x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff,
6310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
6320x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
6330xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
6340x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
6350x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
6360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
6380x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c,
6400xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60,
6410x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
6420x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
6430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc,
6440xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6450x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
6460x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0,
6470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc,
6480xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60,
6490x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
6500x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
6510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06,
6520x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60,
6530x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
6540x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
6550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb,
6560xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6570x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
6580x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
6590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
6600x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
6610x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
6620x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0,
6630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
6640x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
6650x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
6660x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
6670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3,
6680xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6690x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
6700x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3,
6710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
6720xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
6730x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
6740x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e,
6750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
6760x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
6770x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
6780x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
6800xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
6810xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
6820x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
6830x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe,
6840xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
6850x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
6860x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76,
6870x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c,
6880xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38,
6890x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
6900x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06,
6910x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe,
6920xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
6930x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
6940x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
6950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
6960x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
6970x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
6980x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
6990x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6,
7000xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00,
7010x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
7020x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe,
7030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b,
7040x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c,
7050xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
7060x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
7070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
7080xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
7090x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
7100x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
7110x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc,
7120xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
7130x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
7140x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
7150x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
7160xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
7170xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
7180x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc,
7190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18,
7200xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66,
7210x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
7220x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18,
7230xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c,
7240xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
7250x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
7260x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
7270x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc,
7280xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc,
7290x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
7300x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6,
7310x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00,
7320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
7330x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7340x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c,
7350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
7360xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7370x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
7380x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06,
7390x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30,
7400x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
7410x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
7420x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00,
7430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
7440x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
7450x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
7460x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
7470x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
7480xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18,
7490x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7500x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
7510x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
7520x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
7530x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36,
7550x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8,
7560x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
7570x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7580x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7590x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6,
7600x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7610x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7620x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00,
7630x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
7640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7650x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7660x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
7670x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff,
7680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7690x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7700x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
7710x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
7720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
7730x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7740x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
7750x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
7760x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7770x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7780x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
7790x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff,
7800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7810x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7820x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
7830x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
7840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
7850x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7860x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
7870x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff,
7880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7890x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36,
7910x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f,
7920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
7930x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7940x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
7950x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
7960x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7970x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7980x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
7990x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8,
8000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8010x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8020xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8030xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
8040xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
8050xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
8060x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
8070x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
8080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8090x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
8100x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc,
8110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
8120xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8130xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
8140x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe,
8150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8,
8160xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8170x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
8180x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66,
8200x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
8210x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
8220x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee,
8230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66,
8240x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8250x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8260x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0,
8270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60,
8280x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
8290xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
8300x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00,
8310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18,
8320x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
8330x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
8340x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e,
8350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18,
8360x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8370x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
8380x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00,
8390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
8400x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
8410x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
8430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8440x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c,
8450x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
8460x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
8470x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00,
8480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8490x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
8500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8510x00, 0x00, 0x00, 0x00,
852};
diff --git a/arch/powerpc/kernel/head.S b/arch/powerpc/kernel/head.S
index 2c3a1d34e3c7..d49bff1a7d51 100644
--- a/arch/powerpc/kernel/head.S
+++ b/arch/powerpc/kernel/head.S
@@ -134,11 +134,13 @@ __start:
134 * because OF may have I/O devices mapped into that area 134 * because OF may have I/O devices mapped into that area
135 * (particularly on CHRP). 135 * (particularly on CHRP).
136 */ 136 */
137 mr r31,r3 /* save parameters */ 137 cmpwi 0,r5,0
138 beq 1f
139 bl prom_init
140 trap
141
1421: mr r31,r3 /* save parameters */
138 mr r30,r4 143 mr r30,r4
139 mr r29,r5
140 mr r28,r6
141 mr r27,r7
142 li r24,0 /* cpu # */ 144 li r24,0 /* cpu # */
143 145
144/* 146/*
@@ -204,8 +206,7 @@ __after_mmu_off:
204 * On CHRP, we are loaded at 0x10000 since OF on CHRP uses 206 * On CHRP, we are loaded at 0x10000 since OF on CHRP uses
205 * the exception vectors at 0 (and therefore this copy 207 * the exception vectors at 0 (and therefore this copy
206 * overwrites OF's exception vectors with our own). 208 * overwrites OF's exception vectors with our own).
207 * If the MMU is already turned on, we copy stuff to KERNELBASE, 209 * The MMU is off at this point.
208 * otherwise we copy it to 0.
209 */ 210 */
210 bl reloc_offset 211 bl reloc_offset
211 mr r26,r3 212 mr r26,r3
@@ -1187,9 +1188,6 @@ start_here:
1187 */ 1188 */
1188 mr r3,r31 1189 mr r3,r31
1189 mr r4,r30 1190 mr r4,r30
1190 mr r5,r29
1191 mr r6,r28
1192 mr r7,r27
1193 bl machine_init 1191 bl machine_init
1194 bl MMU_init 1192 bl MMU_init
1195 1193
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 33f742cf979b..91a562e3257b 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -212,36 +212,6 @@ EXPORT_SYMBOL(_machine);
212EXPORT_SYMBOL(sys_ctrler); 212EXPORT_SYMBOL(sys_ctrler);
213EXPORT_SYMBOL(pmac_newworld); 213EXPORT_SYMBOL(pmac_newworld);
214#endif 214#endif
215#ifdef CONFIG_PPC_OF
216EXPORT_SYMBOL(find_devices);
217EXPORT_SYMBOL(find_type_devices);
218EXPORT_SYMBOL(find_compatible_devices);
219EXPORT_SYMBOL(find_path_device);
220EXPORT_SYMBOL(device_is_compatible);
221EXPORT_SYMBOL(machine_is_compatible);
222EXPORT_SYMBOL(find_all_nodes);
223EXPORT_SYMBOL(get_property);
224EXPORT_SYMBOL(request_OF_resource);
225EXPORT_SYMBOL(release_OF_resource);
226EXPORT_SYMBOL(pci_busdev_to_OF_node);
227EXPORT_SYMBOL(pci_device_to_OF_node);
228EXPORT_SYMBOL(pci_device_from_OF_node);
229EXPORT_SYMBOL(of_find_node_by_name);
230EXPORT_SYMBOL(of_find_node_by_type);
231EXPORT_SYMBOL(of_find_compatible_node);
232EXPORT_SYMBOL(of_find_node_by_path);
233EXPORT_SYMBOL(of_find_all_nodes);
234EXPORT_SYMBOL(of_get_parent);
235EXPORT_SYMBOL(of_get_next_child);
236EXPORT_SYMBOL(of_node_get);
237EXPORT_SYMBOL(of_node_put);
238#endif /* CONFIG_PPC_OF */
239#if defined(CONFIG_BOOTX_TEXT)
240EXPORT_SYMBOL(btext_update_display);
241#endif
242#if defined(CONFIG_SCSI) && defined(CONFIG_PPC_PMAC)
243EXPORT_SYMBOL(note_scsi_host);
244#endif
245#ifdef CONFIG_VT 215#ifdef CONFIG_VT
246EXPORT_SYMBOL(kd_mksound); 216EXPORT_SYMBOL(kd_mksound);
247#endif 217#endif
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
new file mode 100644
index 000000000000..dc3d24ea3bff
--- /dev/null
+++ b/arch/powerpc/kernel/prom.c
@@ -0,0 +1,2141 @@
1/*
2 * Procedures for creating, accessing and interpreting the device tree.
3 *
4 * Paul Mackerras August 1996.
5 * Copyright (C) 1996-2005 Paul Mackerras.
6 *
7 * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
8 * {engebret|bergner}@us.ibm.com
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#undef DEBUG
17
18#include <stdarg.h>
19#include <linux/config.h>
20#include <linux/kernel.h>
21#include <linux/string.h>
22#include <linux/init.h>
23#include <linux/threads.h>
24#include <linux/spinlock.h>
25#include <linux/types.h>
26#include <linux/pci.h>
27#include <linux/stringify.h>
28#include <linux/delay.h>
29#include <linux/initrd.h>
30#include <linux/bitops.h>
31#include <linux/module.h>
32
33#include <asm/prom.h>
34#include <asm/rtas.h>
35#include <asm/lmb.h>
36#include <asm/page.h>
37#include <asm/processor.h>
38#include <asm/irq.h>
39#include <asm/io.h>
40#include <asm/smp.h>
41#include <asm/system.h>
42#include <asm/mmu.h>
43#include <asm/pgtable.h>
44#include <asm/pci.h>
45#include <asm/iommu.h>
46#include <asm/btext.h>
47#include <asm/sections.h>
48#include <asm/machdep.h>
49#include <asm/pSeries_reconfig.h>
50
51#ifdef DEBUG
52#define DBG(fmt...) printk(KERN_ERR fmt)
53#else
54#define DBG(fmt...)
55#endif
56
57struct pci_reg_property {
58 struct pci_address addr;
59 u32 size_hi;
60 u32 size_lo;
61};
62
63struct isa_reg_property {
64 u32 space;
65 u32 address;
66 u32 size;
67};
68
69
70typedef int interpret_func(struct device_node *, unsigned long *,
71 int, int, int);
72
73extern struct rtas_t rtas;
74extern struct lmb lmb;
75extern unsigned long klimit;
76
77static unsigned long memory_limit;
78
79static int __initdata dt_root_addr_cells;
80static int __initdata dt_root_size_cells;
81
82#ifdef CONFIG_PPC64
83static int __initdata iommu_is_off;
84int __initdata iommu_force_on;
85extern unsigned long tce_alloc_start, tce_alloc_end;
86#endif
87
88typedef u32 cell_t;
89
90#if 0
91static struct boot_param_header *initial_boot_params __initdata;
92#else
93struct boot_param_header *initial_boot_params;
94#endif
95
96static struct device_node *allnodes = NULL;
97
98/* use when traversing tree through the allnext, child, sibling,
99 * or parent members of struct device_node.
100 */
101static DEFINE_RWLOCK(devtree_lock);
102
103/* export that to outside world */
104struct device_node *of_chosen;
105
106struct device_node *dflt_interrupt_controller;
107int num_interrupt_controllers;
108
109u32 rtas_data;
110u32 rtas_entry;
111
112/*
113 * Wrapper for allocating memory for various data that needs to be
114 * attached to device nodes as they are processed at boot or when
115 * added to the device tree later (e.g. DLPAR). At boot there is
116 * already a region reserved so we just increment *mem_start by size;
117 * otherwise we call kmalloc.
118 */
119static void * prom_alloc(unsigned long size, unsigned long *mem_start)
120{
121 unsigned long tmp;
122
123 if (!mem_start)
124 return kmalloc(size, GFP_KERNEL);
125
126 tmp = *mem_start;
127 *mem_start += size;
128 return (void *)tmp;
129}
130
131/*
132 * Find the device_node with a given phandle.
133 */
134static struct device_node * find_phandle(phandle ph)
135{
136 struct device_node *np;
137
138 for (np = allnodes; np != 0; np = np->allnext)
139 if (np->linux_phandle == ph)
140 return np;
141 return NULL;
142}
143
144/*
145 * Find the interrupt parent of a node.
146 */
147static struct device_node * __devinit intr_parent(struct device_node *p)
148{
149 phandle *parp;
150
151 parp = (phandle *) get_property(p, "interrupt-parent", NULL);
152 if (parp == NULL)
153 return p->parent;
154 p = find_phandle(*parp);
155 if (p != NULL)
156 return p;
157 /*
158 * On a powermac booted with BootX, we don't get to know the
159 * phandles for any nodes, so find_phandle will return NULL.
160 * Fortunately these machines only have one interrupt controller
161 * so there isn't in fact any ambiguity. -- paulus
162 */
163 if (num_interrupt_controllers == 1)
164 p = dflt_interrupt_controller;
165 return p;
166}
167
168/*
169 * Find out the size of each entry of the interrupts property
170 * for a node.
171 */
172int __devinit prom_n_intr_cells(struct device_node *np)
173{
174 struct device_node *p;
175 unsigned int *icp;
176
177 for (p = np; (p = intr_parent(p)) != NULL; ) {
178 icp = (unsigned int *)
179 get_property(p, "#interrupt-cells", NULL);
180 if (icp != NULL)
181 return *icp;
182 if (get_property(p, "interrupt-controller", NULL) != NULL
183 || get_property(p, "interrupt-map", NULL) != NULL) {
184 printk("oops, node %s doesn't have #interrupt-cells\n",
185 p->full_name);
186 return 1;
187 }
188 }
189#ifdef DEBUG_IRQ
190 printk("prom_n_intr_cells failed for %s\n", np->full_name);
191#endif
192 return 1;
193}
194
195/*
196 * Map an interrupt from a device up to the platform interrupt
197 * descriptor.
198 */
199static int __devinit map_interrupt(unsigned int **irq, struct device_node **ictrler,
200 struct device_node *np, unsigned int *ints,
201 int nintrc)
202{
203 struct device_node *p, *ipar;
204 unsigned int *imap, *imask, *ip;
205 int i, imaplen, match;
206 int newintrc = 0, newaddrc = 0;
207 unsigned int *reg;
208 int naddrc;
209
210 reg = (unsigned int *) get_property(np, "reg", NULL);
211 naddrc = prom_n_addr_cells(np);
212 p = intr_parent(np);
213 while (p != NULL) {
214 if (get_property(p, "interrupt-controller", NULL) != NULL)
215 /* this node is an interrupt controller, stop here */
216 break;
217 imap = (unsigned int *)
218 get_property(p, "interrupt-map", &imaplen);
219 if (imap == NULL) {
220 p = intr_parent(p);
221 continue;
222 }
223 imask = (unsigned int *)
224 get_property(p, "interrupt-map-mask", NULL);
225 if (imask == NULL) {
226 printk("oops, %s has interrupt-map but no mask\n",
227 p->full_name);
228 return 0;
229 }
230 imaplen /= sizeof(unsigned int);
231 match = 0;
232 ipar = NULL;
233 while (imaplen > 0 && !match) {
234 /* check the child-interrupt field */
235 match = 1;
236 for (i = 0; i < naddrc && match; ++i)
237 match = ((reg[i] ^ imap[i]) & imask[i]) == 0;
238 for (; i < naddrc + nintrc && match; ++i)
239 match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0;
240 imap += naddrc + nintrc;
241 imaplen -= naddrc + nintrc;
242 /* grab the interrupt parent */
243 ipar = find_phandle((phandle) *imap++);
244 --imaplen;
245 if (ipar == NULL && num_interrupt_controllers == 1)
246 /* cope with BootX not giving us phandles */
247 ipar = dflt_interrupt_controller;
248 if (ipar == NULL) {
249 printk("oops, no int parent %x in map of %s\n",
250 imap[-1], p->full_name);
251 return 0;
252 }
253 /* find the parent's # addr and intr cells */
254 ip = (unsigned int *)
255 get_property(ipar, "#interrupt-cells", NULL);
256 if (ip == NULL) {
257 printk("oops, no #interrupt-cells on %s\n",
258 ipar->full_name);
259 return 0;
260 }
261 newintrc = *ip;
262 ip = (unsigned int *)
263 get_property(ipar, "#address-cells", NULL);
264 newaddrc = (ip == NULL)? 0: *ip;
265 imap += newaddrc + newintrc;
266 imaplen -= newaddrc + newintrc;
267 }
268 if (imaplen < 0) {
269 printk("oops, error decoding int-map on %s, len=%d\n",
270 p->full_name, imaplen);
271 return 0;
272 }
273 if (!match) {
274#ifdef DEBUG_IRQ
275 printk("oops, no match in %s int-map for %s\n",
276 p->full_name, np->full_name);
277#endif
278 return 0;
279 }
280 p = ipar;
281 naddrc = newaddrc;
282 nintrc = newintrc;
283 ints = imap - nintrc;
284 reg = ints - naddrc;
285 }
286 if (p == NULL) {
287#ifdef DEBUG_IRQ
288 printk("hmmm, int tree for %s doesn't have ctrler\n",
289 np->full_name);
290#endif
291 return 0;
292 }
293 *irq = ints;
294 *ictrler = p;
295 return nintrc;
296}
297
298static int __devinit finish_node_interrupts(struct device_node *np,
299 unsigned long *mem_start,
300 int measure_only)
301{
302 unsigned int *ints;
303 int intlen, intrcells, intrcount;
304 int i, j, n;
305 unsigned int *irq, virq;
306 struct device_node *ic;
307
308 ints = (unsigned int *) get_property(np, "interrupts", &intlen);
309 if (ints == NULL)
310 return 0;
311 intrcells = prom_n_intr_cells(np);
312 intlen /= intrcells * sizeof(unsigned int);
313
314 np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start);
315 if (!np->intrs)
316 return -ENOMEM;
317
318 if (measure_only)
319 return 0;
320
321 intrcount = 0;
322 for (i = 0; i < intlen; ++i, ints += intrcells) {
323 n = map_interrupt(&irq, &ic, np, ints, intrcells);
324 if (n <= 0)
325 continue;
326
327 /* don't map IRQ numbers under a cascaded 8259 controller */
328 if (ic && device_is_compatible(ic, "chrp,iic")) {
329 np->intrs[intrcount].line = irq[0];
330 } else {
331#ifdef CONFIG_PPC64
332 virq = virt_irq_create_mapping(irq[0]);
333 if (virq == NO_IRQ) {
334 printk(KERN_CRIT "Could not allocate interrupt"
335 " number for %s\n", np->full_name);
336 continue;
337 }
338 virq = irq_offset_up(virq);
339#else
340 virq = irq[0];
341#endif
342 np->intrs[intrcount].line = virq;
343 }
344
345#ifdef CONFIG_PPC64
346 /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
347 if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) {
348 char *name = get_property(ic->parent, "name", NULL);
349 if (name && !strcmp(name, "u3"))
350 np->intrs[intrcount].line += 128;
351 else if (!(name && !strcmp(name, "mac-io")))
352 /* ignore other cascaded controllers, such as
353 the k2-sata-root */
354 break;
355 }
356#endif
357 np->intrs[intrcount].sense = 1;
358 if (n > 1)
359 np->intrs[intrcount].sense = irq[1];
360 if (n > 2) {
361 printk("hmmm, got %d intr cells for %s:", n,
362 np->full_name);
363 for (j = 0; j < n; ++j)
364 printk(" %d", irq[j]);
365 printk("\n");
366 }
367 ++intrcount;
368 }
369 np->n_intrs = intrcount;
370
371 return 0;
372}
373
374static int __devinit interpret_pci_props(struct device_node *np,
375 unsigned long *mem_start,
376 int naddrc, int nsizec,
377 int measure_only)
378{
379 struct address_range *adr;
380 struct pci_reg_property *pci_addrs;
381 int i, l, n_addrs;
382
383 pci_addrs = (struct pci_reg_property *)
384 get_property(np, "assigned-addresses", &l);
385 if (!pci_addrs)
386 return 0;
387
388 n_addrs = l / sizeof(*pci_addrs);
389
390 adr = prom_alloc(n_addrs * sizeof(*adr), mem_start);
391 if (!adr)
392 return -ENOMEM;
393
394 if (measure_only)
395 return 0;
396
397 np->addrs = adr;
398 np->n_addrs = n_addrs;
399
400 for (i = 0; i < n_addrs; i++) {
401 adr[i].space = pci_addrs[i].addr.a_hi;
402 adr[i].address = pci_addrs[i].addr.a_lo |
403 ((u64)pci_addrs[i].addr.a_mid << 32);
404 adr[i].size = pci_addrs[i].size_lo;
405 }
406
407 return 0;
408}
409
410static int __init interpret_dbdma_props(struct device_node *np,
411 unsigned long *mem_start,
412 int naddrc, int nsizec,
413 int measure_only)
414{
415 struct reg_property32 *rp;
416 struct address_range *adr;
417 unsigned long base_address;
418 int i, l;
419 struct device_node *db;
420
421 base_address = 0;
422 if (!measure_only) {
423 for (db = np->parent; db != NULL; db = db->parent) {
424 if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
425 base_address = db->addrs[0].address;
426 break;
427 }
428 }
429 }
430
431 rp = (struct reg_property32 *) get_property(np, "reg", &l);
432 if (rp != 0 && l >= sizeof(struct reg_property32)) {
433 i = 0;
434 adr = (struct address_range *) (*mem_start);
435 while ((l -= sizeof(struct reg_property32)) >= 0) {
436 if (!measure_only) {
437 adr[i].space = 2;
438 adr[i].address = rp[i].address + base_address;
439 adr[i].size = rp[i].size;
440 }
441 ++i;
442 }
443 np->addrs = adr;
444 np->n_addrs = i;
445 (*mem_start) += i * sizeof(struct address_range);
446 }
447
448 return 0;
449}
450
451static int __init interpret_macio_props(struct device_node *np,
452 unsigned long *mem_start,
453 int naddrc, int nsizec,
454 int measure_only)
455{
456 struct reg_property32 *rp;
457 struct address_range *adr;
458 unsigned long base_address;
459 int i, l;
460 struct device_node *db;
461
462 base_address = 0;
463 if (!measure_only) {
464 for (db = np->parent; db != NULL; db = db->parent) {
465 if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
466 base_address = db->addrs[0].address;
467 break;
468 }
469 }
470 }
471
472 rp = (struct reg_property32 *) get_property(np, "reg", &l);
473 if (rp != 0 && l >= sizeof(struct reg_property32)) {
474 i = 0;
475 adr = (struct address_range *) (*mem_start);
476 while ((l -= sizeof(struct reg_property32)) >= 0) {
477 if (!measure_only) {
478 adr[i].space = 2;
479 adr[i].address = rp[i].address + base_address;
480 adr[i].size = rp[i].size;
481 }
482 ++i;
483 }
484 np->addrs = adr;
485 np->n_addrs = i;
486 (*mem_start) += i * sizeof(struct address_range);
487 }
488
489 return 0;
490}
491
492static int __init interpret_isa_props(struct device_node *np,
493 unsigned long *mem_start,
494 int naddrc, int nsizec,
495 int measure_only)
496{
497 struct isa_reg_property *rp;
498 struct address_range *adr;
499 int i, l;
500
501 rp = (struct isa_reg_property *) get_property(np, "reg", &l);
502 if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
503 i = 0;
504 adr = (struct address_range *) (*mem_start);
505 while ((l -= sizeof(struct isa_reg_property)) >= 0) {
506 if (!measure_only) {
507 adr[i].space = rp[i].space;
508 adr[i].address = rp[i].address;
509 adr[i].size = rp[i].size;
510 }
511 ++i;
512 }
513 np->addrs = adr;
514 np->n_addrs = i;
515 (*mem_start) += i * sizeof(struct address_range);
516 }
517
518 return 0;
519}
520
521static int __init interpret_root_props(struct device_node *np,
522 unsigned long *mem_start,
523 int naddrc, int nsizec,
524 int measure_only)
525{
526 struct address_range *adr;
527 int i, l;
528 unsigned int *rp;
529 int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
530
531 rp = (unsigned int *) get_property(np, "reg", &l);
532 if (rp != 0 && l >= rpsize) {
533 i = 0;
534 adr = (struct address_range *) (*mem_start);
535 while ((l -= rpsize) >= 0) {
536 if (!measure_only) {
537 adr[i].space = 0;
538 adr[i].address = rp[naddrc - 1];
539 adr[i].size = rp[naddrc + nsizec - 1];
540 }
541 ++i;
542 rp += naddrc + nsizec;
543 }
544 np->addrs = adr;
545 np->n_addrs = i;
546 (*mem_start) += i * sizeof(struct address_range);
547 }
548
549 return 0;
550}
551
552static int __devinit finish_node(struct device_node *np,
553 unsigned long *mem_start,
554 interpret_func *ifunc,
555 int naddrc, int nsizec,
556 int measure_only)
557{
558 struct device_node *child;
559 int *ip, rc = 0;
560
561 /* get the device addresses and interrupts */
562 if (ifunc != NULL)
563 rc = ifunc(np, mem_start, naddrc, nsizec, measure_only);
564 if (rc)
565 goto out;
566
567 rc = finish_node_interrupts(np, mem_start, measure_only);
568 if (rc)
569 goto out;
570
571 /* Look for #address-cells and #size-cells properties. */
572 ip = (int *) get_property(np, "#address-cells", NULL);
573 if (ip != NULL)
574 naddrc = *ip;
575 ip = (int *) get_property(np, "#size-cells", NULL);
576 if (ip != NULL)
577 nsizec = *ip;
578
579 if (!strcmp(np->name, "device-tree") || np->parent == NULL)
580 ifunc = interpret_root_props;
581 else if (np->type == 0)
582 ifunc = NULL;
583 else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
584 ifunc = interpret_pci_props;
585 else if (!strcmp(np->type, "dbdma"))
586 ifunc = interpret_dbdma_props;
587 else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props)
588 ifunc = interpret_macio_props;
589 else if (!strcmp(np->type, "isa"))
590 ifunc = interpret_isa_props;
591 else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
592 ifunc = interpret_root_props;
593 else if (!((ifunc == interpret_dbdma_props
594 || ifunc == interpret_macio_props)
595 && (!strcmp(np->type, "escc")
596 || !strcmp(np->type, "media-bay"))))
597 ifunc = NULL;
598
599 for (child = np->child; child != NULL; child = child->sibling) {
600 rc = finish_node(child, mem_start, ifunc,
601 naddrc, nsizec, measure_only);
602 if (rc)
603 goto out;
604 }
605out:
606 return rc;
607}
608
609static void __init scan_interrupt_controllers(void)
610{
611 struct device_node *np;
612 int n = 0;
613 char *name, *ic;
614 int iclen;
615
616 for (np = allnodes; np != NULL; np = np->allnext) {
617 ic = get_property(np, "interrupt-controller", &iclen);
618 name = get_property(np, "name", NULL);
619 /* checking iclen makes sure we don't get a false
620 match on /chosen.interrupt_controller */
621 if ((name != NULL
622 && strcmp(name, "interrupt-controller") == 0)
623 || (ic != NULL && iclen == 0
624 && strcmp(name, "AppleKiwi"))) {
625 if (n == 0)
626 dflt_interrupt_controller = np;
627 ++n;
628 }
629 }
630 num_interrupt_controllers = n;
631}
632
633/**
634 * finish_device_tree is called once things are running normally
635 * (i.e. with text and data mapped to the address they were linked at).
636 * It traverses the device tree and fills in some of the additional,
637 * fields in each node like {n_}addrs and {n_}intrs, the virt interrupt
638 * mapping is also initialized at this point.
639 */
640void __init finish_device_tree(void)
641{
642 unsigned long start, end, size = 0;
643
644 DBG(" -> finish_device_tree\n");
645
646#ifdef CONFIG_PPC64
647 /* Initialize virtual IRQ map */
648 virt_irq_init();
649#endif
650 scan_interrupt_controllers();
651
652 /*
653 * Finish device-tree (pre-parsing some properties etc...)
654 * We do this in 2 passes. One with "measure_only" set, which
655 * will only measure the amount of memory needed, then we can
656 * allocate that memory, and call finish_node again. However,
657 * we must be careful as most routines will fail nowadays when
658 * prom_alloc() returns 0, so we must make sure our first pass
659 * doesn't start at 0. We pre-initialize size to 16 for that
660 * reason and then remove those additional 16 bytes
661 */
662 size = 16;
663 finish_node(allnodes, &size, NULL, 0, 0, 1);
664 size -= 16;
665 end = start = (unsigned long) __va(lmb_alloc(size, 128));
666 finish_node(allnodes, &end, NULL, 0, 0, 0);
667 BUG_ON(end != start + size);
668
669 DBG(" <- finish_device_tree\n");
670}
671
672static inline char *find_flat_dt_string(u32 offset)
673{
674 return ((char *)initial_boot_params) +
675 initial_boot_params->off_dt_strings + offset;
676}
677
678/**
679 * This function is used to scan the flattened device-tree, it is
680 * used to extract the memory informations at boot before we can
681 * unflatten the tree
682 */
683static int __init scan_flat_dt(int (*it)(unsigned long node,
684 const char *uname, int depth,
685 void *data),
686 void *data)
687{
688 unsigned long p = ((unsigned long)initial_boot_params) +
689 initial_boot_params->off_dt_struct;
690 int rc = 0;
691 int depth = -1;
692
693 do {
694 u32 tag = *((u32 *)p);
695 char *pathp;
696
697 p += 4;
698 if (tag == OF_DT_END_NODE) {
699 depth --;
700 continue;
701 }
702 if (tag == OF_DT_NOP)
703 continue;
704 if (tag == OF_DT_END)
705 break;
706 if (tag == OF_DT_PROP) {
707 u32 sz = *((u32 *)p);
708 p += 8;
709 if (initial_boot_params->version < 0x10)
710 p = _ALIGN(p, sz >= 8 ? 8 : 4);
711 p += sz;
712 p = _ALIGN(p, 4);
713 continue;
714 }
715 if (tag != OF_DT_BEGIN_NODE) {
716 printk(KERN_WARNING "Invalid tag %x scanning flattened"
717 " device tree !\n", tag);
718 return -EINVAL;
719 }
720 depth++;
721 pathp = (char *)p;
722 p = _ALIGN(p + strlen(pathp) + 1, 4);
723 if ((*pathp) == '/') {
724 char *lp, *np;
725 for (lp = NULL, np = pathp; *np; np++)
726 if ((*np) == '/')
727 lp = np+1;
728 if (lp != NULL)
729 pathp = lp;
730 }
731 rc = it(p, pathp, depth, data);
732 if (rc != 0)
733 break;
734 } while(1);
735
736 return rc;
737}
738
739/**
740 * This function can be used within scan_flattened_dt callback to get
741 * access to properties
742 */
743static void* __init get_flat_dt_prop(unsigned long node, const char *name,
744 unsigned long *size)
745{
746 unsigned long p = node;
747
748 do {
749 u32 tag = *((u32 *)p);
750 u32 sz, noff;
751 const char *nstr;
752
753 p += 4;
754 if (tag == OF_DT_NOP)
755 continue;
756 if (tag != OF_DT_PROP)
757 return NULL;
758
759 sz = *((u32 *)p);
760 noff = *((u32 *)(p + 4));
761 p += 8;
762 if (initial_boot_params->version < 0x10)
763 p = _ALIGN(p, sz >= 8 ? 8 : 4);
764
765 nstr = find_flat_dt_string(noff);
766 if (nstr == NULL) {
767 printk(KERN_WARNING "Can't find property index"
768 " name !\n");
769 return NULL;
770 }
771 if (strcmp(name, nstr) == 0) {
772 if (size)
773 *size = sz;
774 return (void *)p;
775 }
776 p += sz;
777 p = _ALIGN(p, 4);
778 } while(1);
779}
780
781static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
782 unsigned long align)
783{
784 void *res;
785
786 *mem = _ALIGN(*mem, align);
787 res = (void *)*mem;
788 *mem += size;
789
790 return res;
791}
792
793static unsigned long __init unflatten_dt_node(unsigned long mem,
794 unsigned long *p,
795 struct device_node *dad,
796 struct device_node ***allnextpp,
797 unsigned long fpsize)
798{
799 struct device_node *np;
800 struct property *pp, **prev_pp = NULL;
801 char *pathp;
802 u32 tag;
803 unsigned int l, allocl;
804 int has_name = 0;
805 int new_format = 0;
806
807 tag = *((u32 *)(*p));
808 if (tag != OF_DT_BEGIN_NODE) {
809 printk("Weird tag at start of node: %x\n", tag);
810 return mem;
811 }
812 *p += 4;
813 pathp = (char *)*p;
814 l = allocl = strlen(pathp) + 1;
815 *p = _ALIGN(*p + l, 4);
816
817 /* version 0x10 has a more compact unit name here instead of the full
818 * path. we accumulate the full path size using "fpsize", we'll rebuild
819 * it later. We detect this because the first character of the name is
820 * not '/'.
821 */
822 if ((*pathp) != '/') {
823 new_format = 1;
824 if (fpsize == 0) {
825 /* root node: special case. fpsize accounts for path
826 * plus terminating zero. root node only has '/', so
827 * fpsize should be 2, but we want to avoid the first
828 * level nodes to have two '/' so we use fpsize 1 here
829 */
830 fpsize = 1;
831 allocl = 2;
832 } else {
833 /* account for '/' and path size minus terminal 0
834 * already in 'l'
835 */
836 fpsize += l;
837 allocl = fpsize;
838 }
839 }
840
841
842 np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
843 __alignof__(struct device_node));
844 if (allnextpp) {
845 memset(np, 0, sizeof(*np));
846 np->full_name = ((char*)np) + sizeof(struct device_node);
847 if (new_format) {
848 char *p = np->full_name;
849 /* rebuild full path for new format */
850 if (dad && dad->parent) {
851 strcpy(p, dad->full_name);
852#ifdef DEBUG
853 if ((strlen(p) + l + 1) != allocl) {
854 DBG("%s: p: %d, l: %d, a: %d\n",
855 pathp, strlen(p), l, allocl);
856 }
857#endif
858 p += strlen(p);
859 }
860 *(p++) = '/';
861 memcpy(p, pathp, l);
862 } else
863 memcpy(np->full_name, pathp, l);
864 prev_pp = &np->properties;
865 **allnextpp = np;
866 *allnextpp = &np->allnext;
867 if (dad != NULL) {
868 np->parent = dad;
869 /* we temporarily use the next field as `last_child'*/
870 if (dad->next == 0)
871 dad->child = np;
872 else
873 dad->next->sibling = np;
874 dad->next = np;
875 }
876 kref_init(&np->kref);
877 }
878 while(1) {
879 u32 sz, noff;
880 char *pname;
881
882 tag = *((u32 *)(*p));
883 if (tag == OF_DT_NOP) {
884 *p += 4;
885 continue;
886 }
887 if (tag != OF_DT_PROP)
888 break;
889 *p += 4;
890 sz = *((u32 *)(*p));
891 noff = *((u32 *)((*p) + 4));
892 *p += 8;
893 if (initial_boot_params->version < 0x10)
894 *p = _ALIGN(*p, sz >= 8 ? 8 : 4);
895
896 pname = find_flat_dt_string(noff);
897 if (pname == NULL) {
898 printk("Can't find property name in list !\n");
899 break;
900 }
901 if (strcmp(pname, "name") == 0)
902 has_name = 1;
903 l = strlen(pname) + 1;
904 pp = unflatten_dt_alloc(&mem, sizeof(struct property),
905 __alignof__(struct property));
906 if (allnextpp) {
907 if (strcmp(pname, "linux,phandle") == 0) {
908 np->node = *((u32 *)*p);
909 if (np->linux_phandle == 0)
910 np->linux_phandle = np->node;
911 }
912 if (strcmp(pname, "ibm,phandle") == 0)
913 np->linux_phandle = *((u32 *)*p);
914 pp->name = pname;
915 pp->length = sz;
916 pp->value = (void *)*p;
917 *prev_pp = pp;
918 prev_pp = &pp->next;
919 }
920 *p = _ALIGN((*p) + sz, 4);
921 }
922 /* with version 0x10 we may not have the name property, recreate
923 * it here from the unit name if absent
924 */
925 if (!has_name) {
926 char *p = pathp, *ps = pathp, *pa = NULL;
927 int sz;
928
929 while (*p) {
930 if ((*p) == '@')
931 pa = p;
932 if ((*p) == '/')
933 ps = p + 1;
934 p++;
935 }
936 if (pa < ps)
937 pa = p;
938 sz = (pa - ps) + 1;
939 pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
940 __alignof__(struct property));
941 if (allnextpp) {
942 pp->name = "name";
943 pp->length = sz;
944 pp->value = (unsigned char *)(pp + 1);
945 *prev_pp = pp;
946 prev_pp = &pp->next;
947 memcpy(pp->value, ps, sz - 1);
948 ((char *)pp->value)[sz - 1] = 0;
949 DBG("fixed up name for %s -> %s\n", pathp, pp->value);
950 }
951 }
952 if (allnextpp) {
953 *prev_pp = NULL;
954 np->name = get_property(np, "name", NULL);
955 np->type = get_property(np, "device_type", NULL);
956
957 if (!np->name)
958 np->name = "<NULL>";
959 if (!np->type)
960 np->type = "<NULL>";
961 }
962 while (tag == OF_DT_BEGIN_NODE) {
963 mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
964 tag = *((u32 *)(*p));
965 }
966 if (tag != OF_DT_END_NODE) {
967 printk("Weird tag at end of node: %x\n", tag);
968 return mem;
969 }
970 *p += 4;
971 return mem;
972}
973
974
975/**
976 * unflattens the device-tree passed by the firmware, creating the
977 * tree of struct device_node. It also fills the "name" and "type"
978 * pointers of the nodes so the normal device-tree walking functions
979 * can be used (this used to be done by finish_device_tree)
980 */
981void __init unflatten_device_tree(void)
982{
983 unsigned long start, mem, size;
984 struct device_node **allnextp = &allnodes;
985 char *p = NULL;
986 int l = 0;
987
988 DBG(" -> unflatten_device_tree()\n");
989
990 /* First pass, scan for size */
991 start = ((unsigned long)initial_boot_params) +
992 initial_boot_params->off_dt_struct;
993 size = unflatten_dt_node(0, &start, NULL, NULL, 0);
994 size = (size | 3) + 1;
995
996 DBG(" size is %lx, allocating...\n", size);
997
998 /* Allocate memory for the expanded device tree */
999 mem = lmb_alloc(size + 4, __alignof__(struct device_node));
1000 if (!mem) {
1001 DBG("Couldn't allocate memory with lmb_alloc()!\n");
1002 panic("Couldn't allocate memory with lmb_alloc()!\n");
1003 }
1004 mem = (unsigned long) __va(mem);
1005
1006 ((u32 *)mem)[size / 4] = 0xdeadbeef;
1007
1008 DBG(" unflattening %lx...\n", mem);
1009
1010 /* Second pass, do actual unflattening */
1011 start = ((unsigned long)initial_boot_params) +
1012 initial_boot_params->off_dt_struct;
1013 unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
1014 if (*((u32 *)start) != OF_DT_END)
1015 printk(KERN_WARNING "Weird tag at end of tree: %08x\n", *((u32 *)start));
1016 if (((u32 *)mem)[size / 4] != 0xdeadbeef)
1017 printk(KERN_WARNING "End of tree marker overwritten: %08x\n",
1018 ((u32 *)mem)[size / 4] );
1019 *allnextp = NULL;
1020
1021 /* Get pointer to OF "/chosen" node for use everywhere */
1022 of_chosen = of_find_node_by_path("/chosen");
1023
1024 /* Retreive command line */
1025 if (of_chosen != NULL) {
1026 p = (char *)get_property(of_chosen, "bootargs", &l);
1027 if (p != NULL && l > 0)
1028 strlcpy(cmd_line, p, min(l, COMMAND_LINE_SIZE));
1029 }
1030#ifdef CONFIG_CMDLINE
1031 if (l == 0 || (l == 1 && (*p) == 0))
1032 strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
1033#endif /* CONFIG_CMDLINE */
1034
1035 DBG("Command line is: %s\n", cmd_line);
1036
1037 DBG(" <- unflatten_device_tree()\n");
1038}
1039
1040
1041static int __init early_init_dt_scan_cpus(unsigned long node,
1042 const char *uname, int depth, void *data)
1043{
1044 char *type = get_flat_dt_prop(node, "device_type", NULL);
1045 u32 *prop;
1046 unsigned long size = 0;
1047
1048 /* We are scanning "cpu" nodes only */
1049 if (type == NULL || strcmp(type, "cpu") != 0)
1050 return 0;
1051
1052#ifdef CONFIG_PPC_PSERIES
1053 /* On LPAR, look for the first ibm,pft-size property for the hash table size
1054 */
1055 if (systemcfg->platform == PLATFORM_PSERIES_LPAR && ppc64_pft_size == 0) {
1056 u32 *pft_size;
1057 pft_size = get_flat_dt_prop(node, "ibm,pft-size", NULL);
1058 if (pft_size != NULL) {
1059 /* pft_size[0] is the NUMA CEC cookie */
1060 ppc64_pft_size = pft_size[1];
1061 }
1062 }
1063#endif
1064
1065#ifdef CONFIG_PPC64
1066 if (initial_boot_params && initial_boot_params->version >= 2) {
1067 /* version 2 of the kexec param format adds the phys cpuid
1068 * of booted proc.
1069 */
1070 boot_cpuid_phys = initial_boot_params->boot_cpuid_phys;
1071 boot_cpuid = 0;
1072 } else {
1073 /* Check if it's the boot-cpu, set it's hw index in paca now */
1074 if (get_flat_dt_prop(node, "linux,boot-cpu", NULL) != NULL) {
1075 u32 *prop = get_flat_dt_prop(node, "reg", NULL);
1076 set_hard_smp_processor_id(0, prop == NULL ? 0 : *prop);
1077 boot_cpuid_phys = get_hard_smp_processor_id(0);
1078 }
1079 }
1080#endif
1081
1082#ifdef CONFIG_ALTIVEC
1083 /* Check if we have a VMX and eventually update CPU features */
1084 prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", &size);
1085 if (prop && (*prop) > 0) {
1086 cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
1087 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
1088 }
1089
1090 /* Same goes for Apple's "altivec" property */
1091 prop = (u32 *)get_flat_dt_prop(node, "altivec", NULL);
1092 if (prop) {
1093 cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
1094 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
1095 }
1096#endif /* CONFIG_ALTIVEC */
1097
1098#ifdef CONFIG_PPC_PSERIES
1099 /*
1100 * Check for an SMT capable CPU and set the CPU feature. We do
1101 * this by looking at the size of the ibm,ppc-interrupt-server#s
1102 * property
1103 */
1104 prop = (u32 *)get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
1105 &size);
1106 cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
1107 if (prop && ((size / sizeof(u32)) > 1))
1108 cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
1109#endif
1110
1111 return 0;
1112}
1113
1114static int __init early_init_dt_scan_chosen(unsigned long node,
1115 const char *uname, int depth, void *data)
1116{
1117 u32 *prop;
1118 unsigned long *lprop;
1119
1120 DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
1121
1122 if (depth != 1 || strcmp(uname, "chosen") != 0)
1123 return 0;
1124
1125 /* get platform type */
1126 prop = (u32 *)get_flat_dt_prop(node, "linux,platform", NULL);
1127 if (prop == NULL)
1128 return 0;
1129#ifdef CONFIG_PPC64
1130 systemcfg->platform = *prop;
1131#else
1132 _machine = *prop;
1133#endif
1134
1135#ifdef CONFIG_PPC64
1136 /* check if iommu is forced on or off */
1137 if (get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
1138 iommu_is_off = 1;
1139 if (get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL)
1140 iommu_force_on = 1;
1141#endif
1142
1143 lprop = get_flat_dt_prop(node, "linux,memory-limit", NULL);
1144 if (lprop)
1145 memory_limit = *lprop;
1146
1147#ifdef CONFIG_PPC64
1148 lprop = get_flat_dt_prop(node, "linux,tce-alloc-start", NULL);
1149 if (lprop)
1150 tce_alloc_start = *lprop;
1151 lprop = get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
1152 if (lprop)
1153 tce_alloc_end = *lprop;
1154#endif
1155
1156#ifdef CONFIG_PPC_RTAS
1157 /* To help early debugging via the front panel, we retreive a minimal
1158 * set of RTAS infos now if available
1159 */
1160 {
1161 u64 *basep, *entryp;
1162
1163 basep = get_flat_dt_prop(node, "linux,rtas-base", NULL);
1164 entryp = get_flat_dt_prop(node, "linux,rtas-entry", NULL);
1165 prop = get_flat_dt_prop(node, "linux,rtas-size", NULL);
1166 if (basep && entryp && prop) {
1167 rtas.base = *basep;
1168 rtas.entry = *entryp;
1169 rtas.size = *prop;
1170 }
1171 }
1172#endif /* CONFIG_PPC_RTAS */
1173
1174 /* break now */
1175 return 1;
1176}
1177
1178static int __init early_init_dt_scan_root(unsigned long node,
1179 const char *uname, int depth, void *data)
1180{
1181 u32 *prop;
1182
1183 if (depth != 0)
1184 return 0;
1185
1186 prop = get_flat_dt_prop(node, "#size-cells", NULL);
1187 dt_root_size_cells = (prop == NULL) ? 1 : *prop;
1188 DBG("dt_root_size_cells = %x\n", dt_root_size_cells);
1189
1190 prop = get_flat_dt_prop(node, "#address-cells", NULL);
1191 dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
1192 DBG("dt_root_addr_cells = %x\n", dt_root_addr_cells);
1193
1194 /* break now */
1195 return 1;
1196}
1197
1198static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
1199{
1200 cell_t *p = *cellp;
1201 unsigned long r;
1202
1203 /* Ignore more than 2 cells */
1204 while (s > sizeof(unsigned long) / 4) {
1205 p++;
1206 s--;
1207 }
1208 r = *p++;
1209#ifdef CONFIG_PPC64
1210 if (s > 1) {
1211 r <<= 32;
1212 r |= *(p++);
1213 s--;
1214 }
1215#endif
1216
1217 *cellp = p;
1218 return r;
1219}
1220
1221
1222static int __init early_init_dt_scan_memory(unsigned long node,
1223 const char *uname, int depth, void *data)
1224{
1225 char *type = get_flat_dt_prop(node, "device_type", NULL);
1226 cell_t *reg, *endp;
1227 unsigned long l;
1228
1229 /* We are scanning "memory" nodes only */
1230 if (type == NULL || strcmp(type, "memory") != 0)
1231 return 0;
1232
1233 reg = (cell_t *)get_flat_dt_prop(node, "reg", &l);
1234 if (reg == NULL)
1235 return 0;
1236
1237 endp = reg + (l / sizeof(cell_t));
1238
1239 DBG("memory scan node %s ..., reg size %ld, data: %x %x %x %x, ...\n",
1240 uname, l, reg[0], reg[1], reg[2], reg[3]);
1241
1242 while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
1243 unsigned long base, size;
1244
1245 base = dt_mem_next_cell(dt_root_addr_cells, &reg);
1246 size = dt_mem_next_cell(dt_root_size_cells, &reg);
1247
1248 if (size == 0)
1249 continue;
1250 DBG(" - %lx , %lx\n", base, size);
1251#ifdef CONFIG_PPC64
1252 if (iommu_is_off) {
1253 if (base >= 0x80000000ul)
1254 continue;
1255 if ((base + size) > 0x80000000ul)
1256 size = 0x80000000ul - base;
1257 }
1258#endif
1259 lmb_add(base, size);
1260 }
1261 return 0;
1262}
1263
1264static void __init early_reserve_mem(void)
1265{
1266 unsigned long base, size;
1267 unsigned long *reserve_map;
1268
1269 reserve_map = (unsigned long *)(((unsigned long)initial_boot_params) +
1270 initial_boot_params->off_mem_rsvmap);
1271 while (1) {
1272 base = *(reserve_map++);
1273 size = *(reserve_map++);
1274 if (size == 0)
1275 break;
1276 DBG("reserving: %lx -> %lx\n", base, size);
1277 lmb_reserve(base, size);
1278 }
1279
1280#if 0
1281 DBG("memory reserved, lmbs :\n");
1282 lmb_dump_all();
1283#endif
1284}
1285
1286void __init early_init_devtree(void *params)
1287{
1288 DBG(" -> early_init_devtree()\n");
1289
1290 /* Setup flat device-tree pointer */
1291 initial_boot_params = params;
1292
1293 /* Retrieve various informations from the /chosen node of the
1294 * device-tree, including the platform type, initrd location and
1295 * size, TCE reserve, and more ...
1296 */
1297 scan_flat_dt(early_init_dt_scan_chosen, NULL);
1298
1299 /* Scan memory nodes and rebuild LMBs */
1300 lmb_init();
1301 scan_flat_dt(early_init_dt_scan_root, NULL);
1302 scan_flat_dt(early_init_dt_scan_memory, NULL);
1303 lmb_enforce_memory_limit(memory_limit);
1304 lmb_analyze();
1305#ifdef CONFIG_PPC64
1306 systemcfg->physicalMemorySize = lmb_phys_mem_size();
1307#endif
1308 lmb_reserve(0, __pa(klimit));
1309
1310 DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
1311
1312 /* Reserve LMB regions used by kernel, initrd, dt, etc... */
1313 early_reserve_mem();
1314
1315 DBG("Scanning CPUs ...\n");
1316
1317 /* Retreive hash table size from flattened tree plus other
1318 * CPU related informations (altivec support, boot CPU ID, ...)
1319 */
1320 scan_flat_dt(early_init_dt_scan_cpus, NULL);
1321
1322#ifdef CONFIG_PPC_PSERIES
1323 /* If hash size wasn't obtained above, we calculate it now based on
1324 * the total RAM size
1325 */
1326 if (ppc64_pft_size == 0) {
1327 unsigned long rnd_mem_size, pteg_count;
1328
1329 /* round mem_size up to next power of 2 */
1330 rnd_mem_size = 1UL << __ilog2(systemcfg->physicalMemorySize);
1331 if (rnd_mem_size < systemcfg->physicalMemorySize)
1332 rnd_mem_size <<= 1;
1333
1334 /* # pages / 2 */
1335 pteg_count = max(rnd_mem_size >> (12 + 1), 1UL << 11);
1336
1337 ppc64_pft_size = __ilog2(pteg_count << 7);
1338 }
1339
1340 DBG("Hash pftSize: %x\n", (int)ppc64_pft_size);
1341#endif
1342 DBG(" <- early_init_devtree()\n");
1343}
1344
1345#undef printk
1346
1347int
1348prom_n_addr_cells(struct device_node* np)
1349{
1350 int* ip;
1351 do {
1352 if (np->parent)
1353 np = np->parent;
1354 ip = (int *) get_property(np, "#address-cells", NULL);
1355 if (ip != NULL)
1356 return *ip;
1357 } while (np->parent);
1358 /* No #address-cells property for the root node, default to 1 */
1359 return 1;
1360}
1361
1362int
1363prom_n_size_cells(struct device_node* np)
1364{
1365 int* ip;
1366 do {
1367 if (np->parent)
1368 np = np->parent;
1369 ip = (int *) get_property(np, "#size-cells", NULL);
1370 if (ip != NULL)
1371 return *ip;
1372 } while (np->parent);
1373 /* No #size-cells property for the root node, default to 1 */
1374 return 1;
1375}
1376
1377/**
1378 * Work out the sense (active-low level / active-high edge)
1379 * of each interrupt from the device tree.
1380 */
1381void __init prom_get_irq_senses(unsigned char *senses, int off, int max)
1382{
1383 struct device_node *np;
1384 int i, j;
1385
1386 /* default to level-triggered */
1387 memset(senses, 1, max - off);
1388
1389 for (np = allnodes; np != 0; np = np->allnext) {
1390 for (j = 0; j < np->n_intrs; j++) {
1391 i = np->intrs[j].line;
1392 if (i >= off && i < max)
1393 senses[i-off] = np->intrs[j].sense ?
1394 IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE :
1395 IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE;
1396 }
1397 }
1398}
1399
1400/**
1401 * Construct and return a list of the device_nodes with a given name.
1402 */
1403struct device_node *find_devices(const char *name)
1404{
1405 struct device_node *head, **prevp, *np;
1406
1407 prevp = &head;
1408 for (np = allnodes; np != 0; np = np->allnext) {
1409 if (np->name != 0 && strcasecmp(np->name, name) == 0) {
1410 *prevp = np;
1411 prevp = &np->next;
1412 }
1413 }
1414 *prevp = NULL;
1415 return head;
1416}
1417EXPORT_SYMBOL(find_devices);
1418
1419/**
1420 * Construct and return a list of the device_nodes with a given type.
1421 */
1422struct device_node *find_type_devices(const char *type)
1423{
1424 struct device_node *head, **prevp, *np;
1425
1426 prevp = &head;
1427 for (np = allnodes; np != 0; np = np->allnext) {
1428 if (np->type != 0 && strcasecmp(np->type, type) == 0) {
1429 *prevp = np;
1430 prevp = &np->next;
1431 }
1432 }
1433 *prevp = NULL;
1434 return head;
1435}
1436EXPORT_SYMBOL(find_type_devices);
1437
1438/**
1439 * Returns all nodes linked together
1440 */
1441struct device_node *find_all_nodes(void)
1442{
1443 struct device_node *head, **prevp, *np;
1444
1445 prevp = &head;
1446 for (np = allnodes; np != 0; np = np->allnext) {
1447 *prevp = np;
1448 prevp = &np->next;
1449 }
1450 *prevp = NULL;
1451 return head;
1452}
1453EXPORT_SYMBOL(find_all_nodes);
1454
1455/** Checks if the given "compat" string matches one of the strings in
1456 * the device's "compatible" property
1457 */
1458int device_is_compatible(struct device_node *device, const char *compat)
1459{
1460 const char* cp;
1461 int cplen, l;
1462
1463 cp = (char *) get_property(device, "compatible", &cplen);
1464 if (cp == NULL)
1465 return 0;
1466 while (cplen > 0) {
1467 if (strncasecmp(cp, compat, strlen(compat)) == 0)
1468 return 1;
1469 l = strlen(cp) + 1;
1470 cp += l;
1471 cplen -= l;
1472 }
1473
1474 return 0;
1475}
1476EXPORT_SYMBOL(device_is_compatible);
1477
1478
1479/**
1480 * Indicates whether the root node has a given value in its
1481 * compatible property.
1482 */
1483int machine_is_compatible(const char *compat)
1484{
1485 struct device_node *root;
1486 int rc = 0;
1487
1488 root = of_find_node_by_path("/");
1489 if (root) {
1490 rc = device_is_compatible(root, compat);
1491 of_node_put(root);
1492 }
1493 return rc;
1494}
1495EXPORT_SYMBOL(machine_is_compatible);
1496
1497/**
1498 * Construct and return a list of the device_nodes with a given type
1499 * and compatible property.
1500 */
1501struct device_node *find_compatible_devices(const char *type,
1502 const char *compat)
1503{
1504 struct device_node *head, **prevp, *np;
1505
1506 prevp = &head;
1507 for (np = allnodes; np != 0; np = np->allnext) {
1508 if (type != NULL
1509 && !(np->type != 0 && strcasecmp(np->type, type) == 0))
1510 continue;
1511 if (device_is_compatible(np, compat)) {
1512 *prevp = np;
1513 prevp = &np->next;
1514 }
1515 }
1516 *prevp = NULL;
1517 return head;
1518}
1519EXPORT_SYMBOL(find_compatible_devices);
1520
1521/**
1522 * Find the device_node with a given full_name.
1523 */
1524struct device_node *find_path_device(const char *path)
1525{
1526 struct device_node *np;
1527
1528 for (np = allnodes; np != 0; np = np->allnext)
1529 if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
1530 return np;
1531 return NULL;
1532}
1533EXPORT_SYMBOL(find_path_device);
1534
1535/*******
1536 *
1537 * New implementation of the OF "find" APIs, return a refcounted
1538 * object, call of_node_put() when done. The device tree and list
1539 * are protected by a rw_lock.
1540 *
1541 * Note that property management will need some locking as well,
1542 * this isn't dealt with yet.
1543 *
1544 *******/
1545
1546/**
1547 * of_find_node_by_name - Find a node by its "name" property
1548 * @from: The node to start searching from or NULL, the node
1549 * you pass will not be searched, only the next one
1550 * will; typically, you pass what the previous call
1551 * returned. of_node_put() will be called on it
1552 * @name: The name string to match against
1553 *
1554 * Returns a node pointer with refcount incremented, use
1555 * of_node_put() on it when done.
1556 */
1557struct device_node *of_find_node_by_name(struct device_node *from,
1558 const char *name)
1559{
1560 struct device_node *np;
1561
1562 read_lock(&devtree_lock);
1563 np = from ? from->allnext : allnodes;
1564 for (; np != 0; np = np->allnext)
1565 if (np->name != 0 && strcasecmp(np->name, name) == 0
1566 && of_node_get(np))
1567 break;
1568 if (from)
1569 of_node_put(from);
1570 read_unlock(&devtree_lock);
1571 return np;
1572}
1573EXPORT_SYMBOL(of_find_node_by_name);
1574
1575/**
1576 * of_find_node_by_type - Find a node by its "device_type" property
1577 * @from: The node to start searching from or NULL, the node
1578 * you pass will not be searched, only the next one
1579 * will; typically, you pass what the previous call
1580 * returned. of_node_put() will be called on it
1581 * @name: The type string to match against
1582 *
1583 * Returns a node pointer with refcount incremented, use
1584 * of_node_put() on it when done.
1585 */
1586struct device_node *of_find_node_by_type(struct device_node *from,
1587 const char *type)
1588{
1589 struct device_node *np;
1590
1591 read_lock(&devtree_lock);
1592 np = from ? from->allnext : allnodes;
1593 for (; np != 0; np = np->allnext)
1594 if (np->type != 0 && strcasecmp(np->type, type) == 0
1595 && of_node_get(np))
1596 break;
1597 if (from)
1598 of_node_put(from);
1599 read_unlock(&devtree_lock);
1600 return np;
1601}
1602EXPORT_SYMBOL(of_find_node_by_type);
1603
1604/**
1605 * of_find_compatible_node - Find a node based on type and one of the
1606 * tokens in its "compatible" property
1607 * @from: The node to start searching from or NULL, the node
1608 * you pass will not be searched, only the next one
1609 * will; typically, you pass what the previous call
1610 * returned. of_node_put() will be called on it
1611 * @type: The type string to match "device_type" or NULL to ignore
1612 * @compatible: The string to match to one of the tokens in the device
1613 * "compatible" list.
1614 *
1615 * Returns a node pointer with refcount incremented, use
1616 * of_node_put() on it when done.
1617 */
1618struct device_node *of_find_compatible_node(struct device_node *from,
1619 const char *type, const char *compatible)
1620{
1621 struct device_node *np;
1622
1623 read_lock(&devtree_lock);
1624 np = from ? from->allnext : allnodes;
1625 for (; np != 0; np = np->allnext) {
1626 if (type != NULL
1627 && !(np->type != 0 && strcasecmp(np->type, type) == 0))
1628 continue;
1629 if (device_is_compatible(np, compatible) && of_node_get(np))
1630 break;
1631 }
1632 if (from)
1633 of_node_put(from);
1634 read_unlock(&devtree_lock);
1635 return np;
1636}
1637EXPORT_SYMBOL(of_find_compatible_node);
1638
1639/**
1640 * of_find_node_by_path - Find a node matching a full OF path
1641 * @path: The full path to match
1642 *
1643 * Returns a node pointer with refcount incremented, use
1644 * of_node_put() on it when done.
1645 */
1646struct device_node *of_find_node_by_path(const char *path)
1647{
1648 struct device_node *np = allnodes;
1649
1650 read_lock(&devtree_lock);
1651 for (; np != 0; np = np->allnext) {
1652 if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0
1653 && of_node_get(np))
1654 break;
1655 }
1656 read_unlock(&devtree_lock);
1657 return np;
1658}
1659EXPORT_SYMBOL(of_find_node_by_path);
1660
1661/**
1662 * of_find_node_by_phandle - Find a node given a phandle
1663 * @handle: phandle of the node to find
1664 *
1665 * Returns a node pointer with refcount incremented, use
1666 * of_node_put() on it when done.
1667 */
1668struct device_node *of_find_node_by_phandle(phandle handle)
1669{
1670 struct device_node *np;
1671
1672 read_lock(&devtree_lock);
1673 for (np = allnodes; np != 0; np = np->allnext)
1674 if (np->linux_phandle == handle)
1675 break;
1676 if (np)
1677 of_node_get(np);
1678 read_unlock(&devtree_lock);
1679 return np;
1680}
1681EXPORT_SYMBOL(of_find_node_by_phandle);
1682
1683/**
1684 * of_find_all_nodes - Get next node in global list
1685 * @prev: Previous node or NULL to start iteration
1686 * of_node_put() will be called on it
1687 *
1688 * Returns a node pointer with refcount incremented, use
1689 * of_node_put() on it when done.
1690 */
1691struct device_node *of_find_all_nodes(struct device_node *prev)
1692{
1693 struct device_node *np;
1694
1695 read_lock(&devtree_lock);
1696 np = prev ? prev->allnext : allnodes;
1697 for (; np != 0; np = np->allnext)
1698 if (of_node_get(np))
1699 break;
1700 if (prev)
1701 of_node_put(prev);
1702 read_unlock(&devtree_lock);
1703 return np;
1704}
1705EXPORT_SYMBOL(of_find_all_nodes);
1706
1707/**
1708 * of_get_parent - Get a node's parent if any
1709 * @node: Node to get parent
1710 *
1711 * Returns a node pointer with refcount incremented, use
1712 * of_node_put() on it when done.
1713 */
1714struct device_node *of_get_parent(const struct device_node *node)
1715{
1716 struct device_node *np;
1717
1718 if (!node)
1719 return NULL;
1720
1721 read_lock(&devtree_lock);
1722 np = of_node_get(node->parent);
1723 read_unlock(&devtree_lock);
1724 return np;
1725}
1726EXPORT_SYMBOL(of_get_parent);
1727
1728/**
1729 * of_get_next_child - Iterate a node childs
1730 * @node: parent node
1731 * @prev: previous child of the parent node, or NULL to get first
1732 *
1733 * Returns a node pointer with refcount incremented, use
1734 * of_node_put() on it when done.
1735 */
1736struct device_node *of_get_next_child(const struct device_node *node,
1737 struct device_node *prev)
1738{
1739 struct device_node *next;
1740
1741 read_lock(&devtree_lock);
1742 next = prev ? prev->sibling : node->child;
1743 for (; next != 0; next = next->sibling)
1744 if (of_node_get(next))
1745 break;
1746 if (prev)
1747 of_node_put(prev);
1748 read_unlock(&devtree_lock);
1749 return next;
1750}
1751EXPORT_SYMBOL(of_get_next_child);
1752
1753/**
1754 * of_node_get - Increment refcount of a node
1755 * @node: Node to inc refcount, NULL is supported to
1756 * simplify writing of callers
1757 *
1758 * Returns node.
1759 */
1760struct device_node *of_node_get(struct device_node *node)
1761{
1762 if (node)
1763 kref_get(&node->kref);
1764 return node;
1765}
1766EXPORT_SYMBOL(of_node_get);
1767
1768static inline struct device_node * kref_to_device_node(struct kref *kref)
1769{
1770 return container_of(kref, struct device_node, kref);
1771}
1772
1773/**
1774 * of_node_release - release a dynamically allocated node
1775 * @kref: kref element of the node to be released
1776 *
1777 * In of_node_put() this function is passed to kref_put()
1778 * as the destructor.
1779 */
1780static void of_node_release(struct kref *kref)
1781{
1782 struct device_node *node = kref_to_device_node(kref);
1783 struct property *prop = node->properties;
1784
1785 if (!OF_IS_DYNAMIC(node))
1786 return;
1787 while (prop) {
1788 struct property *next = prop->next;
1789 kfree(prop->name);
1790 kfree(prop->value);
1791 kfree(prop);
1792 prop = next;
1793 }
1794 kfree(node->intrs);
1795 kfree(node->addrs);
1796 kfree(node->full_name);
1797 kfree(node->data);
1798 kfree(node);
1799}
1800
1801/**
1802 * of_node_put - Decrement refcount of a node
1803 * @node: Node to dec refcount, NULL is supported to
1804 * simplify writing of callers
1805 *
1806 */
1807void of_node_put(struct device_node *node)
1808{
1809 if (node)
1810 kref_put(&node->kref, of_node_release);
1811}
1812EXPORT_SYMBOL(of_node_put);
1813
1814/*
1815 * Plug a device node into the tree and global list.
1816 */
1817void of_attach_node(struct device_node *np)
1818{
1819 write_lock(&devtree_lock);
1820 np->sibling = np->parent->child;
1821 np->allnext = allnodes;
1822 np->parent->child = np;
1823 allnodes = np;
1824 write_unlock(&devtree_lock);
1825}
1826
1827/*
1828 * "Unplug" a node from the device tree. The caller must hold
1829 * a reference to the node. The memory associated with the node
1830 * is not freed until its refcount goes to zero.
1831 */
1832void of_detach_node(const struct device_node *np)
1833{
1834 struct device_node *parent;
1835
1836 write_lock(&devtree_lock);
1837
1838 parent = np->parent;
1839
1840 if (allnodes == np)
1841 allnodes = np->allnext;
1842 else {
1843 struct device_node *prev;
1844 for (prev = allnodes;
1845 prev->allnext != np;
1846 prev = prev->allnext)
1847 ;
1848 prev->allnext = np->allnext;
1849 }
1850
1851 if (parent->child == np)
1852 parent->child = np->sibling;
1853 else {
1854 struct device_node *prevsib;
1855 for (prevsib = np->parent->child;
1856 prevsib->sibling != np;
1857 prevsib = prevsib->sibling)
1858 ;
1859 prevsib->sibling = np->sibling;
1860 }
1861
1862 write_unlock(&devtree_lock);
1863}
1864
1865#ifdef CONFIG_PPC_PSERIES
1866/*
1867 * Fix up the uninitialized fields in a new device node:
1868 * name, type, n_addrs, addrs, n_intrs, intrs, and pci-specific fields
1869 *
1870 * A lot of boot-time code is duplicated here, because functions such
1871 * as finish_node_interrupts, interpret_pci_props, etc. cannot use the
1872 * slab allocator.
1873 *
1874 * This should probably be split up into smaller chunks.
1875 */
1876
1877static int of_finish_dynamic_node(struct device_node *node,
1878 unsigned long *unused1, int unused2,
1879 int unused3, int unused4)
1880{
1881 struct device_node *parent = of_get_parent(node);
1882 int err = 0;
1883 phandle *ibm_phandle;
1884
1885 node->name = get_property(node, "name", NULL);
1886 node->type = get_property(node, "device_type", NULL);
1887
1888 if (!parent) {
1889 err = -ENODEV;
1890 goto out;
1891 }
1892
1893 /* We don't support that function on PowerMac, at least
1894 * not yet
1895 */
1896 if (systemcfg->platform == PLATFORM_POWERMAC)
1897 return -ENODEV;
1898
1899 /* fix up new node's linux_phandle field */
1900 if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL)))
1901 node->linux_phandle = *ibm_phandle;
1902
1903out:
1904 of_node_put(parent);
1905 return err;
1906}
1907
1908static int prom_reconfig_notifier(struct notifier_block *nb,
1909 unsigned long action, void *node)
1910{
1911 int err;
1912
1913 switch (action) {
1914 case PSERIES_RECONFIG_ADD:
1915 err = finish_node(node, NULL, of_finish_dynamic_node, 0, 0, 0);
1916 if (err < 0) {
1917 printk(KERN_ERR "finish_node returned %d\n", err);
1918 err = NOTIFY_BAD;
1919 }
1920 break;
1921 default:
1922 err = NOTIFY_DONE;
1923 break;
1924 }
1925 return err;
1926}
1927
1928static struct notifier_block prom_reconfig_nb = {
1929 .notifier_call = prom_reconfig_notifier,
1930 .priority = 10, /* This one needs to run first */
1931};
1932
1933static int __init prom_reconfig_setup(void)
1934{
1935 return pSeries_reconfig_notifier_register(&prom_reconfig_nb);
1936}
1937__initcall(prom_reconfig_setup);
1938#endif
1939
1940/*
1941 * Find a property with a given name for a given node
1942 * and return the value.
1943 */
1944unsigned char *get_property(struct device_node *np, const char *name,
1945 int *lenp)
1946{
1947 struct property *pp;
1948
1949 for (pp = np->properties; pp != 0; pp = pp->next)
1950 if (strcmp(pp->name, name) == 0) {
1951 if (lenp != 0)
1952 *lenp = pp->length;
1953 return pp->value;
1954 }
1955 return NULL;
1956}
1957EXPORT_SYMBOL(get_property);
1958
1959/*
1960 * Add a property to a node
1961 */
1962void prom_add_property(struct device_node* np, struct property* prop)
1963{
1964 struct property **next = &np->properties;
1965
1966 prop->next = NULL;
1967 while (*next)
1968 next = &(*next)->next;
1969 *next = prop;
1970}
1971
1972/* I quickly hacked that one, check against spec ! */
1973static inline unsigned long
1974bus_space_to_resource_flags(unsigned int bus_space)
1975{
1976 u8 space = (bus_space >> 24) & 0xf;
1977 if (space == 0)
1978 space = 0x02;
1979 if (space == 0x02)
1980 return IORESOURCE_MEM;
1981 else if (space == 0x01)
1982 return IORESOURCE_IO;
1983 else {
1984 printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n",
1985 bus_space);
1986 return 0;
1987 }
1988}
1989
1990static struct resource *find_parent_pci_resource(struct pci_dev* pdev,
1991 struct address_range *range)
1992{
1993 unsigned long mask;
1994 int i;
1995
1996 /* Check this one */
1997 mask = bus_space_to_resource_flags(range->space);
1998 for (i=0; i<DEVICE_COUNT_RESOURCE; i++) {
1999 if ((pdev->resource[i].flags & mask) == mask &&
2000 pdev->resource[i].start <= range->address &&
2001 pdev->resource[i].end > range->address) {
2002 if ((range->address + range->size - 1) > pdev->resource[i].end) {
2003 /* Add better message */
2004 printk(KERN_WARNING "PCI/OF resource overlap !\n");
2005 return NULL;
2006 }
2007 break;
2008 }
2009 }
2010 if (i == DEVICE_COUNT_RESOURCE)
2011 return NULL;
2012 return &pdev->resource[i];
2013}
2014
2015/*
2016 * Request an OF device resource. Currently handles child of PCI devices,
2017 * or other nodes attached to the root node. Ultimately, put some
2018 * link to resources in the OF node.
2019 */
2020struct resource *request_OF_resource(struct device_node* node, int index,
2021 const char* name_postfix)
2022{
2023 struct pci_dev* pcidev;
2024 u8 pci_bus, pci_devfn;
2025 unsigned long iomask;
2026 struct device_node* nd;
2027 struct resource* parent;
2028 struct resource *res = NULL;
2029 int nlen, plen;
2030
2031 if (index >= node->n_addrs)
2032 goto fail;
2033
2034 /* Sanity check on bus space */
2035 iomask = bus_space_to_resource_flags(node->addrs[index].space);
2036 if (iomask & IORESOURCE_MEM)
2037 parent = &iomem_resource;
2038 else if (iomask & IORESOURCE_IO)
2039 parent = &ioport_resource;
2040 else
2041 goto fail;
2042
2043 /* Find a PCI parent if any */
2044 nd = node;
2045 pcidev = NULL;
2046 while (nd) {
2047 if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
2048 pcidev = pci_find_slot(pci_bus, pci_devfn);
2049 if (pcidev) break;
2050 nd = nd->parent;
2051 }
2052 if (pcidev)
2053 parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
2054 if (!parent) {
2055 printk(KERN_WARNING "request_OF_resource(%s), parent not found\n",
2056 node->name);
2057 goto fail;
2058 }
2059
2060 res = __request_region(parent, node->addrs[index].address,
2061 node->addrs[index].size, NULL);
2062 if (!res)
2063 goto fail;
2064 nlen = strlen(node->name);
2065 plen = name_postfix ? strlen(name_postfix) : 0;
2066 res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL);
2067 if (res->name) {
2068 strcpy((char *)res->name, node->name);
2069 if (plen)
2070 strcpy((char *)res->name+nlen, name_postfix);
2071 }
2072 return res;
2073fail:
2074 return NULL;
2075}
2076EXPORT_SYMBOL(request_OF_resource);
2077
2078int release_OF_resource(struct device_node *node, int index)
2079{
2080 struct pci_dev* pcidev;
2081 u8 pci_bus, pci_devfn;
2082 unsigned long iomask, start, end;
2083 struct device_node* nd;
2084 struct resource* parent;
2085 struct resource *res = NULL;
2086
2087 if (index >= node->n_addrs)
2088 return -EINVAL;
2089
2090 /* Sanity check on bus space */
2091 iomask = bus_space_to_resource_flags(node->addrs[index].space);
2092 if (iomask & IORESOURCE_MEM)
2093 parent = &iomem_resource;
2094 else if (iomask & IORESOURCE_IO)
2095 parent = &ioport_resource;
2096 else
2097 return -EINVAL;
2098
2099 /* Find a PCI parent if any */
2100 nd = node;
2101 pcidev = NULL;
2102 while(nd) {
2103 if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
2104 pcidev = pci_find_slot(pci_bus, pci_devfn);
2105 if (pcidev) break;
2106 nd = nd->parent;
2107 }
2108 if (pcidev)
2109 parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
2110 if (!parent) {
2111 printk(KERN_WARNING "release_OF_resource(%s), parent not found\n",
2112 node->name);
2113 return -ENODEV;
2114 }
2115
2116 /* Find us in the parent and its childs */
2117 res = parent->child;
2118 start = node->addrs[index].address;
2119 end = start + node->addrs[index].size - 1;
2120 while (res) {
2121 if (res->start == start && res->end == end &&
2122 (res->flags & IORESOURCE_BUSY))
2123 break;
2124 if (res->start <= start && res->end >= end)
2125 res = res->child;
2126 else
2127 res = res->sibling;
2128 }
2129 if (!res)
2130 return -ENODEV;
2131
2132 if (res->name) {
2133 kfree(res->name);
2134 res->name = NULL;
2135 }
2136 release_resource(res);
2137 kfree(res);
2138
2139 return 0;
2140}
2141EXPORT_SYMBOL(release_OF_resource);
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
new file mode 100644
index 000000000000..e01cda1454c9
--- /dev/null
+++ b/arch/powerpc/kernel/prom_init.c
@@ -0,0 +1,2126 @@
1/*
2 * Procedures for interfacing to Open Firmware.
3 *
4 * Paul Mackerras August 1996.
5 * Copyright (C) 1996-2005 Paul Mackerras.
6 *
7 * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
8 * {engebret|bergner}@us.ibm.com
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#undef DEBUG_PROM
17
18#include <stdarg.h>
19#include <linux/config.h>
20#include <linux/kernel.h>
21#include <linux/string.h>
22#include <linux/init.h>
23#include <linux/threads.h>
24#include <linux/spinlock.h>
25#include <linux/types.h>
26#include <linux/pci.h>
27#include <linux/proc_fs.h>
28#include <linux/stringify.h>
29#include <linux/delay.h>
30#include <linux/initrd.h>
31#include <linux/bitops.h>
32#include <asm/prom.h>
33#include <asm/rtas.h>
34#include <asm/page.h>
35#include <asm/processor.h>
36#include <asm/irq.h>
37#include <asm/io.h>
38#include <asm/smp.h>
39#include <asm/system.h>
40#include <asm/mmu.h>
41#include <asm/pgtable.h>
42#include <asm/pci.h>
43#include <asm/iommu.h>
44#include <asm/bootinfo.h>
45#include <asm/btext.h>
46#include <asm/sections.h>
47#include <asm/machdep.h>
48
49#ifdef CONFIG_LOGO_LINUX_CLUT224
50#include <linux/linux_logo.h>
51extern const struct linux_logo logo_linux_clut224;
52#endif
53
54/*
55 * Properties whose value is longer than this get excluded from our
56 * copy of the device tree. This value does need to be big enough to
57 * ensure that we don't lose things like the interrupt-map property
58 * on a PCI-PCI bridge.
59 */
60#define MAX_PROPERTY_LENGTH (1UL * 1024 * 1024)
61
62/*
63 * Eventually bump that one up
64 */
65#define DEVTREE_CHUNK_SIZE 0x100000
66
67/*
68 * This is the size of the local memory reserve map that gets copied
69 * into the boot params passed to the kernel. That size is totally
70 * flexible as the kernel just reads the list until it encounters an
71 * entry with size 0, so it can be changed without breaking binary
72 * compatibility
73 */
74#define MEM_RESERVE_MAP_SIZE 8
75
76/*
77 * prom_init() is called very early on, before the kernel text
78 * and data have been mapped to KERNELBASE. At this point the code
79 * is running at whatever address it has been loaded at.
80 * On ppc32 we compile with -mrelocatable, which means that references
81 * to extern and static variables get relocated automatically.
82 * On ppc64 we have to relocate the references explicitly with
83 * RELOC. (Note that strings count as static variables.)
84 *
85 * Because OF may have mapped I/O devices into the area starting at
86 * KERNELBASE, particularly on CHRP machines, we can't safely call
87 * OF once the kernel has been mapped to KERNELBASE. Therefore all
88 * OF calls must be done within prom_init().
89 *
90 * ADDR is used in calls to call_prom. The 4th and following
91 * arguments to call_prom should be 32-bit values.
92 * On ppc64, 64 bit values are truncated to 32 bits (and
93 * fortunately don't get interpreted as two arguments).
94 */
95#ifdef CONFIG_PPC64
96#define RELOC(x) (*PTRRELOC(&(x)))
97#define ADDR(x) (u32) add_reloc_offset((unsigned long)(x))
98#else
99#define RELOC(x) (x)
100#define ADDR(x) (u32) (x)
101#endif
102
103#define PROM_BUG() do { \
104 prom_printf("kernel BUG at %s line 0x%x!\n", \
105 RELOC(__FILE__), __LINE__); \
106 __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
107} while (0)
108
109#ifdef DEBUG_PROM
110#define prom_debug(x...) prom_printf(x)
111#else
112#define prom_debug(x...)
113#endif
114
115#ifdef CONFIG_PPC32
116#define PLATFORM_POWERMAC _MACH_Pmac
117#define PLATFORM_CHRP _MACH_chrp
118#endif
119
120
121typedef u32 prom_arg_t;
122
123struct prom_args {
124 u32 service;
125 u32 nargs;
126 u32 nret;
127 prom_arg_t args[10];
128};
129
130struct prom_t {
131 ihandle root;
132 ihandle chosen;
133 int cpu;
134 ihandle stdout;
135};
136
137struct mem_map_entry {
138 unsigned long base;
139 unsigned long size;
140};
141
142typedef u32 cell_t;
143
144extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);
145
146#ifdef CONFIG_PPC64
147extern void enter_prom(struct prom_args *args, unsigned long entry);
148#else
149static inline void enter_prom(struct prom_args *args, unsigned long entry)
150{
151 ((void (*)(struct prom_args *))entry)(args);
152}
153#endif
154
155extern void copy_and_flush(unsigned long dest, unsigned long src,
156 unsigned long size, unsigned long offset);
157
158/* prom structure */
159static struct prom_t __initdata prom;
160
161static unsigned long prom_entry __initdata;
162
163#define PROM_SCRATCH_SIZE 256
164
165static char __initdata of_stdout_device[256];
166static char __initdata prom_scratch[PROM_SCRATCH_SIZE];
167
168static unsigned long __initdata dt_header_start;
169static unsigned long __initdata dt_struct_start, dt_struct_end;
170static unsigned long __initdata dt_string_start, dt_string_end;
171
172static unsigned long __initdata prom_initrd_start, prom_initrd_end;
173
174#ifdef CONFIG_PPC64
175static int __initdata iommu_force_on;
176static int __initdata ppc64_iommu_off;
177static unsigned long __initdata prom_tce_alloc_start;
178static unsigned long __initdata prom_tce_alloc_end;
179#endif
180
181static int __initdata of_platform;
182
183static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
184
185static unsigned long __initdata prom_memory_limit;
186
187static unsigned long __initdata alloc_top;
188static unsigned long __initdata alloc_top_high;
189static unsigned long __initdata alloc_bottom;
190static unsigned long __initdata rmo_top;
191static unsigned long __initdata ram_top;
192
193static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
194static int __initdata mem_reserve_cnt;
195
196static cell_t __initdata regbuf[1024];
197
198
199#define MAX_CPU_THREADS 2
200
201/* TO GO */
202#ifdef CONFIG_HMT
203struct {
204 unsigned int pir;
205 unsigned int threadid;
206} hmt_thread_data[NR_CPUS];
207#endif /* CONFIG_HMT */
208
209/*
210 * Error results ... some OF calls will return "-1" on error, some
211 * will return 0, some will return either. To simplify, here are
212 * macros to use with any ihandle or phandle return value to check if
213 * it is valid
214 */
215
216#define PROM_ERROR (-1u)
217#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR)
218#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR)
219
220
221/* This is the one and *ONLY* place where we actually call open
222 * firmware.
223 */
224
225static int __init call_prom(const char *service, int nargs, int nret, ...)
226{
227 int i;
228 struct prom_args args;
229 va_list list;
230
231 args.service = ADDR(service);
232 args.nargs = nargs;
233 args.nret = nret;
234
235 va_start(list, nret);
236 for (i = 0; i < nargs; i++)
237 args.args[i] = va_arg(list, prom_arg_t);
238 va_end(list);
239
240 for (i = 0; i < nret; i++)
241 args.args[nargs+i] = 0;
242
243 enter_prom(&args, RELOC(prom_entry));
244
245 return (nret > 0) ? args.args[nargs] : 0;
246}
247
248static int __init call_prom_ret(const char *service, int nargs, int nret,
249 prom_arg_t *rets, ...)
250{
251 int i;
252 struct prom_args args;
253 va_list list;
254
255 args.service = ADDR(service);
256 args.nargs = nargs;
257 args.nret = nret;
258
259 va_start(list, rets);
260 for (i = 0; i < nargs; i++)
261 args.args[i] = va_arg(list, prom_arg_t);
262 va_end(list);
263
264 for (i = 0; i < nret; i++)
265 rets[nargs+i] = 0;
266
267 enter_prom(&args, RELOC(prom_entry));
268
269 if (rets != NULL)
270 for (i = 1; i < nret; ++i)
271 rets[i] = args.args[nargs+i];
272
273 return (nret > 0) ? args.args[nargs] : 0;
274}
275
276
277static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
278 unsigned long align)
279{
280 return (unsigned int)call_prom("claim", 3, 1,
281 (prom_arg_t)virt, (prom_arg_t)size,
282 (prom_arg_t)align);
283}
284
285static void __init prom_print(const char *msg)
286{
287 const char *p, *q;
288 struct prom_t *_prom = &RELOC(prom);
289
290 if (_prom->stdout == 0)
291 return;
292
293 for (p = msg; *p != 0; p = q) {
294 for (q = p; *q != 0 && *q != '\n'; ++q)
295 ;
296 if (q > p)
297 call_prom("write", 3, 1, _prom->stdout, p, q - p);
298 if (*q == 0)
299 break;
300 ++q;
301 call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2);
302 }
303}
304
305
306static void __init prom_print_hex(unsigned long val)
307{
308 int i, nibbles = sizeof(val)*2;
309 char buf[sizeof(val)*2+1];
310 struct prom_t *_prom = &RELOC(prom);
311
312 for (i = nibbles-1; i >= 0; i--) {
313 buf[i] = (val & 0xf) + '0';
314 if (buf[i] > '9')
315 buf[i] += ('a'-'0'-10);
316 val >>= 4;
317 }
318 buf[nibbles] = '\0';
319 call_prom("write", 3, 1, _prom->stdout, buf, nibbles);
320}
321
322
323static void __init prom_printf(const char *format, ...)
324{
325 const char *p, *q, *s;
326 va_list args;
327 unsigned long v;
328 struct prom_t *_prom = &RELOC(prom);
329
330 va_start(args, format);
331#ifdef CONFIG_PPC64
332 format = PTRRELOC(format);
333#endif
334 for (p = format; *p != 0; p = q) {
335 for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
336 ;
337 if (q > p)
338 call_prom("write", 3, 1, _prom->stdout, p, q - p);
339 if (*q == 0)
340 break;
341 if (*q == '\n') {
342 ++q;
343 call_prom("write", 3, 1, _prom->stdout,
344 ADDR("\r\n"), 2);
345 continue;
346 }
347 ++q;
348 if (*q == 0)
349 break;
350 switch (*q) {
351 case 's':
352 ++q;
353 s = va_arg(args, const char *);
354 prom_print(s);
355 break;
356 case 'x':
357 ++q;
358 v = va_arg(args, unsigned long);
359 prom_print_hex(v);
360 break;
361 }
362 }
363}
364
365
366static void __init __attribute__((noreturn)) prom_panic(const char *reason)
367{
368#ifdef CONFIG_PPC64
369 reason = PTRRELOC(reason);
370#endif
371 prom_print(reason);
372 /* ToDo: should put up an SRC here on p/iSeries */
373 call_prom("exit", 0, 0);
374
375 for (;;) /* should never get here */
376 ;
377}
378
379
380static int __init prom_next_node(phandle *nodep)
381{
382 phandle node;
383
384 if ((node = *nodep) != 0
385 && (*nodep = call_prom("child", 1, 1, node)) != 0)
386 return 1;
387 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
388 return 1;
389 for (;;) {
390 if ((node = call_prom("parent", 1, 1, node)) == 0)
391 return 0;
392 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
393 return 1;
394 }
395}
396
397static int __init prom_getprop(phandle node, const char *pname,
398 void *value, size_t valuelen)
399{
400 return call_prom("getprop", 4, 1, node, ADDR(pname),
401 (u32)(unsigned long) value, (u32) valuelen);
402}
403
404static int __init prom_getproplen(phandle node, const char *pname)
405{
406 return call_prom("getproplen", 2, 1, node, ADDR(pname));
407}
408
409static int __init prom_setprop(phandle node, const char *pname,
410 void *value, size_t valuelen)
411{
412 return call_prom("setprop", 4, 1, node, ADDR(pname),
413 (u32)(unsigned long) value, (u32) valuelen);
414}
415
416/* We can't use the standard versions because of RELOC headaches. */
417#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
418 || ('a' <= (c) && (c) <= 'f') \
419 || ('A' <= (c) && (c) <= 'F'))
420
421#define isdigit(c) ('0' <= (c) && (c) <= '9')
422#define islower(c) ('a' <= (c) && (c) <= 'z')
423#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c))
424
425unsigned long prom_strtoul(const char *cp, const char **endp)
426{
427 unsigned long result = 0, base = 10, value;
428
429 if (*cp == '0') {
430 base = 8;
431 cp++;
432 if (toupper(*cp) == 'X') {
433 cp++;
434 base = 16;
435 }
436 }
437
438 while (isxdigit(*cp) &&
439 (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
440 result = result * base + value;
441 cp++;
442 }
443
444 if (endp)
445 *endp = cp;
446
447 return result;
448}
449
450unsigned long prom_memparse(const char *ptr, const char **retptr)
451{
452 unsigned long ret = prom_strtoul(ptr, retptr);
453 int shift = 0;
454
455 /*
456 * We can't use a switch here because GCC *may* generate a
457 * jump table which won't work, because we're not running at
458 * the address we're linked at.
459 */
460 if ('G' == **retptr || 'g' == **retptr)
461 shift = 30;
462
463 if ('M' == **retptr || 'm' == **retptr)
464 shift = 20;
465
466 if ('K' == **retptr || 'k' == **retptr)
467 shift = 10;
468
469 if (shift) {
470 ret <<= shift;
471 (*retptr)++;
472 }
473
474 return ret;
475}
476
477/*
478 * Early parsing of the command line passed to the kernel, used for
479 * "mem=x" and the options that affect the iommu
480 */
481static void __init early_cmdline_parse(void)
482{
483 struct prom_t *_prom = &RELOC(prom);
484 char *opt, *p;
485 int l = 0;
486
487 RELOC(prom_cmd_line[0]) = 0;
488 p = RELOC(prom_cmd_line);
489 if ((long)_prom->chosen > 0)
490 l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
491#ifdef CONFIG_CMDLINE
492 if (l == 0) /* dbl check */
493 strlcpy(RELOC(prom_cmd_line),
494 RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line));
495#endif /* CONFIG_CMDLINE */
496 prom_printf("command line: %s\n", RELOC(prom_cmd_line));
497
498#ifdef CONFIG_PPC64
499 opt = strstr(RELOC(prom_cmd_line), RELOC("iommu="));
500 if (opt) {
501 prom_printf("iommu opt is: %s\n", opt);
502 opt += 6;
503 while (*opt && *opt == ' ')
504 opt++;
505 if (!strncmp(opt, RELOC("off"), 3))
506 RELOC(ppc64_iommu_off) = 1;
507 else if (!strncmp(opt, RELOC("force"), 5))
508 RELOC(iommu_force_on) = 1;
509 }
510#endif
511
512 opt = strstr(RELOC(prom_cmd_line), RELOC("mem="));
513 if (opt) {
514 opt += 4;
515 RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt);
516#ifdef CONFIG_PPC64
517 /* Align to 16 MB == size of ppc64 large page */
518 RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
519#endif
520 }
521}
522
523#ifdef CONFIG_PPC_PSERIES
524/*
525 * To tell the firmware what our capabilities are, we have to pass
526 * it a fake 32-bit ELF header containing a couple of PT_NOTE sections
527 * that contain structures that contain the actual values.
528 */
529static struct fake_elf {
530 Elf32_Ehdr elfhdr;
531 Elf32_Phdr phdr[2];
532 struct chrpnote {
533 u32 namesz;
534 u32 descsz;
535 u32 type;
536 char name[8]; /* "PowerPC" */
537 struct chrpdesc {
538 u32 real_mode;
539 u32 real_base;
540 u32 real_size;
541 u32 virt_base;
542 u32 virt_size;
543 u32 load_base;
544 } chrpdesc;
545 } chrpnote;
546 struct rpanote {
547 u32 namesz;
548 u32 descsz;
549 u32 type;
550 char name[24]; /* "IBM,RPA-Client-Config" */
551 struct rpadesc {
552 u32 lpar_affinity;
553 u32 min_rmo_size;
554 u32 min_rmo_percent;
555 u32 max_pft_size;
556 u32 splpar;
557 u32 min_load;
558 u32 new_mem_def;
559 u32 ignore_me;
560 } rpadesc;
561 } rpanote;
562} fake_elf = {
563 .elfhdr = {
564 .e_ident = { 0x7f, 'E', 'L', 'F',
565 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
566 .e_type = ET_EXEC, /* yeah right */
567 .e_machine = EM_PPC,
568 .e_version = EV_CURRENT,
569 .e_phoff = offsetof(struct fake_elf, phdr),
570 .e_phentsize = sizeof(Elf32_Phdr),
571 .e_phnum = 2
572 },
573 .phdr = {
574 [0] = {
575 .p_type = PT_NOTE,
576 .p_offset = offsetof(struct fake_elf, chrpnote),
577 .p_filesz = sizeof(struct chrpnote)
578 }, [1] = {
579 .p_type = PT_NOTE,
580 .p_offset = offsetof(struct fake_elf, rpanote),
581 .p_filesz = sizeof(struct rpanote)
582 }
583 },
584 .chrpnote = {
585 .namesz = sizeof("PowerPC"),
586 .descsz = sizeof(struct chrpdesc),
587 .type = 0x1275,
588 .name = "PowerPC",
589 .chrpdesc = {
590 .real_mode = ~0U, /* ~0 means "don't care" */
591 .real_base = ~0U,
592 .real_size = ~0U,
593 .virt_base = ~0U,
594 .virt_size = ~0U,
595 .load_base = ~0U
596 },
597 },
598 .rpanote = {
599 .namesz = sizeof("IBM,RPA-Client-Config"),
600 .descsz = sizeof(struct rpadesc),
601 .type = 0x12759999,
602 .name = "IBM,RPA-Client-Config",
603 .rpadesc = {
604 .lpar_affinity = 0,
605 .min_rmo_size = 64, /* in megabytes */
606 .min_rmo_percent = 0,
607 .max_pft_size = 48, /* 2^48 bytes max PFT size */
608 .splpar = 1,
609 .min_load = ~0U,
610 .new_mem_def = 0
611 }
612 }
613};
614
615static void __init prom_send_capabilities(void)
616{
617 ihandle elfloader;
618
619 elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
620 if (elfloader == 0) {
621 prom_printf("couldn't open /packages/elf-loader\n");
622 return;
623 }
624 call_prom("call-method", 3, 1, ADDR("process-elf-header"),
625 elfloader, ADDR(&fake_elf));
626 call_prom("close", 1, 0, elfloader);
627}
628#endif
629
630/*
631 * Memory allocation strategy... our layout is normally:
632 *
633 * at 14Mb or more we have vmlinux, then a gap and initrd. In some
634 * rare cases, initrd might end up being before the kernel though.
635 * We assume this won't override the final kernel at 0, we have no
636 * provision to handle that in this version, but it should hopefully
637 * never happen.
638 *
639 * alloc_top is set to the top of RMO, eventually shrink down if the
640 * TCEs overlap
641 *
642 * alloc_bottom is set to the top of kernel/initrd
643 *
644 * from there, allocations are done this way : rtas is allocated
645 * topmost, and the device-tree is allocated from the bottom. We try
646 * to grow the device-tree allocation as we progress. If we can't,
647 * then we fail, we don't currently have a facility to restart
648 * elsewhere, but that shouldn't be necessary.
649 *
650 * Note that calls to reserve_mem have to be done explicitly, memory
651 * allocated with either alloc_up or alloc_down isn't automatically
652 * reserved.
653 */
654
655
656/*
657 * Allocates memory in the RMO upward from the kernel/initrd
658 *
659 * When align is 0, this is a special case, it means to allocate in place
660 * at the current location of alloc_bottom or fail (that is basically
661 * extending the previous allocation). Used for the device-tree flattening
662 */
663static unsigned long __init alloc_up(unsigned long size, unsigned long align)
664{
665 unsigned long base = _ALIGN_UP(RELOC(alloc_bottom), align);
666 unsigned long addr = 0;
667
668 prom_debug("alloc_up(%x, %x)\n", size, align);
669 if (RELOC(ram_top) == 0)
670 prom_panic("alloc_up() called with mem not initialized\n");
671
672 if (align)
673 base = _ALIGN_UP(RELOC(alloc_bottom), align);
674 else
675 base = RELOC(alloc_bottom);
676
677 for(; (base + size) <= RELOC(alloc_top);
678 base = _ALIGN_UP(base + 0x100000, align)) {
679 prom_debug(" trying: 0x%x\n\r", base);
680 addr = (unsigned long)prom_claim(base, size, 0);
681 if (addr != PROM_ERROR)
682 break;
683 addr = 0;
684 if (align == 0)
685 break;
686 }
687 if (addr == 0)
688 return 0;
689 RELOC(alloc_bottom) = addr;
690
691 prom_debug(" -> %x\n", addr);
692 prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
693 prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
694 prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
695 prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
696 prom_debug(" ram_top : %x\n", RELOC(ram_top));
697
698 return addr;
699}
700
701/*
702 * Allocates memory downward, either from top of RMO, or if highmem
703 * is set, from the top of RAM. Note that this one doesn't handle
704 * failures. It does claim memory if highmem is not set.
705 */
706static unsigned long __init alloc_down(unsigned long size, unsigned long align,
707 int highmem)
708{
709 unsigned long base, addr = 0;
710
711 prom_debug("alloc_down(%x, %x, %s)\n", size, align,
712 highmem ? RELOC("(high)") : RELOC("(low)"));
713 if (RELOC(ram_top) == 0)
714 prom_panic("alloc_down() called with mem not initialized\n");
715
716 if (highmem) {
717 /* Carve out storage for the TCE table. */
718 addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align);
719 if (addr <= RELOC(alloc_bottom))
720 return 0;
721 /* Will we bump into the RMO ? If yes, check out that we
722 * didn't overlap existing allocations there, if we did,
723 * we are dead, we must be the first in town !
724 */
725 if (addr < RELOC(rmo_top)) {
726 /* Good, we are first */
727 if (RELOC(alloc_top) == RELOC(rmo_top))
728 RELOC(alloc_top) = RELOC(rmo_top) = addr;
729 else
730 return 0;
731 }
732 RELOC(alloc_top_high) = addr;
733 goto bail;
734 }
735
736 base = _ALIGN_DOWN(RELOC(alloc_top) - size, align);
737 for (; base > RELOC(alloc_bottom);
738 base = _ALIGN_DOWN(base - 0x100000, align)) {
739 prom_debug(" trying: 0x%x\n\r", base);
740 addr = (unsigned long)prom_claim(base, size, 0);
741 if (addr != PROM_ERROR)
742 break;
743 addr = 0;
744 }
745 if (addr == 0)
746 return 0;
747 RELOC(alloc_top) = addr;
748
749 bail:
750 prom_debug(" -> %x\n", addr);
751 prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
752 prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
753 prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
754 prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
755 prom_debug(" ram_top : %x\n", RELOC(ram_top));
756
757 return addr;
758}
759
760/*
761 * Parse a "reg" cell
762 */
763static unsigned long __init prom_next_cell(int s, cell_t **cellp)
764{
765 cell_t *p = *cellp;
766 unsigned long r = 0;
767
768 /* Ignore more than 2 cells */
769 while (s > sizeof(unsigned long) / 4) {
770 p++;
771 s--;
772 }
773 r = *p++;
774#ifdef CONFIG_PPC64
775 if (s) {
776 r <<= 32;
777 r |= *(p++);
778 }
779#endif
780 *cellp = p;
781 return r;
782}
783
784/*
785 * Very dumb function for adding to the memory reserve list, but
786 * we don't need anything smarter at this point
787 *
788 * XXX Eventually check for collisions. They should NEVER happen.
789 * If problems seem to show up, it would be a good start to track
790 * them down.
791 */
792static void reserve_mem(unsigned long base, unsigned long size)
793{
794 unsigned long top = base + size;
795 unsigned long cnt = RELOC(mem_reserve_cnt);
796
797 if (size == 0)
798 return;
799
800 /* We need to always keep one empty entry so that we
801 * have our terminator with "size" set to 0 since we are
802 * dumb and just copy this entire array to the boot params
803 */
804 base = _ALIGN_DOWN(base, PAGE_SIZE);
805 top = _ALIGN_UP(top, PAGE_SIZE);
806 size = top - base;
807
808 if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
809 prom_panic("Memory reserve map exhausted !\n");
810 RELOC(mem_reserve_map)[cnt].base = base;
811 RELOC(mem_reserve_map)[cnt].size = size;
812 RELOC(mem_reserve_cnt) = cnt + 1;
813}
814
815/*
816 * Initialize memory allocation mecanism, parse "memory" nodes and
817 * obtain that way the top of memory and RMO to setup out local allocator
818 */
819static void __init prom_init_mem(void)
820{
821 phandle node;
822 char *path, type[64];
823 unsigned int plen;
824 cell_t *p, *endp;
825 struct prom_t *_prom = &RELOC(prom);
826 u32 rac, rsc;
827
828 /*
829 * We iterate the memory nodes to find
830 * 1) top of RMO (first node)
831 * 2) top of memory
832 */
833 rac = 2;
834 prom_getprop(_prom->root, "#address-cells", &rac, sizeof(rac));
835 rsc = 1;
836 prom_getprop(_prom->root, "#size-cells", &rsc, sizeof(rsc));
837 prom_debug("root_addr_cells: %x\n", (unsigned long) rac);
838 prom_debug("root_size_cells: %x\n", (unsigned long) rsc);
839
840 prom_debug("scanning memory:\n");
841 path = RELOC(prom_scratch);
842
843 for (node = 0; prom_next_node(&node); ) {
844 type[0] = 0;
845 prom_getprop(node, "device_type", type, sizeof(type));
846
847 if (strcmp(type, RELOC("memory")))
848 continue;
849
850 plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf));
851 if (plen > sizeof(regbuf)) {
852 prom_printf("memory node too large for buffer !\n");
853 plen = sizeof(regbuf);
854 }
855 p = RELOC(regbuf);
856 endp = p + (plen / sizeof(cell_t));
857
858#ifdef DEBUG_PROM
859 memset(path, 0, PROM_SCRATCH_SIZE);
860 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
861 prom_debug(" node %s :\n", path);
862#endif /* DEBUG_PROM */
863
864 while ((endp - p) >= (rac + rsc)) {
865 unsigned long base, size;
866
867 base = prom_next_cell(rac, &p);
868 size = prom_next_cell(rsc, &p);
869
870 if (size == 0)
871 continue;
872 prom_debug(" %x %x\n", base, size);
873 if (base == 0)
874 RELOC(rmo_top) = size;
875 if ((base + size) > RELOC(ram_top))
876 RELOC(ram_top) = base + size;
877 }
878 }
879
880 RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000);
881
882 /* Check if we have an initrd after the kernel, if we do move our bottom
883 * point to after it
884 */
885 if (RELOC(prom_initrd_start)) {
886 if (RELOC(prom_initrd_end) > RELOC(alloc_bottom))
887 RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
888 }
889
890 /*
891 * If prom_memory_limit is set we reduce the upper limits *except* for
892 * alloc_top_high. This must be the real top of RAM so we can put
893 * TCE's up there.
894 */
895
896 RELOC(alloc_top_high) = RELOC(ram_top);
897
898 if (RELOC(prom_memory_limit)) {
899 if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) {
900 prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
901 RELOC(prom_memory_limit));
902 RELOC(prom_memory_limit) = 0;
903 } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) {
904 prom_printf("Ignoring mem=%x >= ram_top.\n",
905 RELOC(prom_memory_limit));
906 RELOC(prom_memory_limit) = 0;
907 } else {
908 RELOC(ram_top) = RELOC(prom_memory_limit);
909 RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit));
910 }
911 }
912
913 /*
914 * Setup our top alloc point, that is top of RMO or top of
915 * segment 0 when running non-LPAR.
916 * Some RS64 machines have buggy firmware where claims up at
917 * 1GB fail. Cap at 768MB as a workaround.
918 * Since 768MB is plenty of room, and we need to cap to something
919 * reasonable on 32-bit, cap at 768MB on all machines.
920 */
921 if (!RELOC(rmo_top))
922 RELOC(rmo_top) = RELOC(ram_top);
923 RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top));
924 RELOC(alloc_top) = RELOC(rmo_top);
925
926 prom_printf("memory layout at init:\n");
927 prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
928 prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom));
929 prom_printf(" alloc_top : %x\n", RELOC(alloc_top));
930 prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
931 prom_printf(" rmo_top : %x\n", RELOC(rmo_top));
932 prom_printf(" ram_top : %x\n", RELOC(ram_top));
933}
934
935
936/*
937 * Allocate room for and instantiate RTAS
938 */
939static void __init prom_instantiate_rtas(void)
940{
941 phandle rtas_node;
942 ihandle rtas_inst;
943 u32 base, entry = 0;
944 u32 size = 0;
945
946 prom_debug("prom_instantiate_rtas: start...\n");
947
948 rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
949 prom_debug("rtas_node: %x\n", rtas_node);
950 if (!PHANDLE_VALID(rtas_node))
951 return;
952
953 prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
954 if (size == 0)
955 return;
956
957 base = alloc_down(size, PAGE_SIZE, 0);
958 if (base == 0) {
959 prom_printf("RTAS allocation failed !\n");
960 return;
961 }
962
963 rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
964 if (!IHANDLE_VALID(rtas_inst)) {
965 prom_printf("opening rtas package failed");
966 return;
967 }
968
969 prom_printf("instantiating rtas at 0x%x ...", base);
970
971 if (call_prom_ret("call-method", 3, 2, &entry,
972 ADDR("instantiate-rtas"),
973 rtas_inst, base) == PROM_ERROR
974 || entry == 0) {
975 prom_printf(" failed\n");
976 return;
977 }
978 prom_printf(" done\n");
979
980 reserve_mem(base, size);
981
982 prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base));
983 prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry));
984
985 prom_debug("rtas base = 0x%x\n", base);
986 prom_debug("rtas entry = 0x%x\n", entry);
987 prom_debug("rtas size = 0x%x\n", (long)size);
988
989 prom_debug("prom_instantiate_rtas: end...\n");
990}
991
992#ifdef CONFIG_PPC64
993/*
994 * Allocate room for and initialize TCE tables
995 */
996static void __init prom_initialize_tce_table(void)
997{
998 phandle node;
999 ihandle phb_node;
1000 char compatible[64], type[64], model[64];
1001 char *path = RELOC(prom_scratch);
1002 u64 base, align;
1003 u32 minalign, minsize;
1004 u64 tce_entry, *tce_entryp;
1005 u64 local_alloc_top, local_alloc_bottom;
1006 u64 i;
1007
1008 if (RELOC(ppc64_iommu_off))
1009 return;
1010
1011 prom_debug("starting prom_initialize_tce_table\n");
1012
1013 /* Cache current top of allocs so we reserve a single block */
1014 local_alloc_top = RELOC(alloc_top_high);
1015 local_alloc_bottom = local_alloc_top;
1016
1017 /* Search all nodes looking for PHBs. */
1018 for (node = 0; prom_next_node(&node); ) {
1019 compatible[0] = 0;
1020 type[0] = 0;
1021 model[0] = 0;
1022 prom_getprop(node, "compatible",
1023 compatible, sizeof(compatible));
1024 prom_getprop(node, "device_type", type, sizeof(type));
1025 prom_getprop(node, "model", model, sizeof(model));
1026
1027 if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL))
1028 continue;
1029
1030 /* Keep the old logic in tack to avoid regression. */
1031 if (compatible[0] != 0) {
1032 if ((strstr(compatible, RELOC("python")) == NULL) &&
1033 (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
1034 (strstr(compatible, RELOC("Winnipeg")) == NULL))
1035 continue;
1036 } else if (model[0] != 0) {
1037 if ((strstr(model, RELOC("ython")) == NULL) &&
1038 (strstr(model, RELOC("peedwagon")) == NULL) &&
1039 (strstr(model, RELOC("innipeg")) == NULL))
1040 continue;
1041 }
1042
1043 if (prom_getprop(node, "tce-table-minalign", &minalign,
1044 sizeof(minalign)) == PROM_ERROR)
1045 minalign = 0;
1046 if (prom_getprop(node, "tce-table-minsize", &minsize,
1047 sizeof(minsize)) == PROM_ERROR)
1048 minsize = 4UL << 20;
1049
1050 /*
1051 * Even though we read what OF wants, we just set the table
1052 * size to 4 MB. This is enough to map 2GB of PCI DMA space.
1053 * By doing this, we avoid the pitfalls of trying to DMA to
1054 * MMIO space and the DMA alias hole.
1055 *
1056 * On POWER4, firmware sets the TCE region by assuming
1057 * each TCE table is 8MB. Using this memory for anything
1058 * else will impact performance, so we always allocate 8MB.
1059 * Anton
1060 */
1061 if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
1062 minsize = 8UL << 20;
1063 else
1064 minsize = 4UL << 20;
1065
1066 /* Align to the greater of the align or size */
1067 align = max(minalign, minsize);
1068 base = alloc_down(minsize, align, 1);
1069 if (base == 0)
1070 prom_panic("ERROR, cannot find space for TCE table.\n");
1071 if (base < local_alloc_bottom)
1072 local_alloc_bottom = base;
1073
1074 /* Save away the TCE table attributes for later use. */
1075 prom_setprop(node, "linux,tce-base", &base, sizeof(base));
1076 prom_setprop(node, "linux,tce-size", &minsize, sizeof(minsize));
1077
1078 /* It seems OF doesn't null-terminate the path :-( */
1079 memset(path, 0, sizeof(path));
1080 /* Call OF to setup the TCE hardware */
1081 if (call_prom("package-to-path", 3, 1, node,
1082 path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
1083 prom_printf("package-to-path failed\n");
1084 }
1085
1086 prom_debug("TCE table: %s\n", path);
1087 prom_debug("\tnode = 0x%x\n", node);
1088 prom_debug("\tbase = 0x%x\n", base);
1089 prom_debug("\tsize = 0x%x\n", minsize);
1090
1091 /* Initialize the table to have a one-to-one mapping
1092 * over the allocated size.
1093 */
1094 tce_entryp = (unsigned long *)base;
1095 for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
1096 tce_entry = (i << PAGE_SHIFT);
1097 tce_entry |= 0x3;
1098 *tce_entryp = tce_entry;
1099 }
1100
1101 prom_printf("opening PHB %s", path);
1102 phb_node = call_prom("open", 1, 1, path);
1103 if (phb_node == 0)
1104 prom_printf("... failed\n");
1105 else
1106 prom_printf("... done\n");
1107
1108 call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
1109 phb_node, -1, minsize,
1110 (u32) base, (u32) (base >> 32));
1111 call_prom("close", 1, 0, phb_node);
1112 }
1113
1114 reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
1115
1116 if (RELOC(prom_memory_limit)) {
1117 /*
1118 * We align the start to a 16MB boundary so we can map
1119 * the TCE area using large pages if possible.
1120 * The end should be the top of RAM so no need to align it.
1121 */
1122 RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom,
1123 0x1000000);
1124 RELOC(prom_tce_alloc_end) = local_alloc_top;
1125 }
1126
1127 /* Flag the first invalid entry */
1128 prom_debug("ending prom_initialize_tce_table\n");
1129}
1130#endif
1131
1132/*
1133 * With CHRP SMP we need to use the OF to start the other processors.
1134 * We can't wait until smp_boot_cpus (the OF is trashed by then)
1135 * so we have to put the processors into a holding pattern controlled
1136 * by the kernel (not OF) before we destroy the OF.
1137 *
1138 * This uses a chunk of low memory, puts some holding pattern
1139 * code there and sends the other processors off to there until
1140 * smp_boot_cpus tells them to do something. The holding pattern
1141 * checks that address until its cpu # is there, when it is that
1142 * cpu jumps to __secondary_start(). smp_boot_cpus() takes care
1143 * of setting those values.
1144 *
1145 * We also use physical address 0x4 here to tell when a cpu
1146 * is in its holding pattern code.
1147 *
1148 * -- Cort
1149 */
1150static void __init prom_hold_cpus(void)
1151{
1152#ifdef CONFIG_PPC64
1153 unsigned long i;
1154 unsigned int reg;
1155 phandle node;
1156 char type[64];
1157 int cpuid = 0;
1158 unsigned int interrupt_server[MAX_CPU_THREADS];
1159 unsigned int cpu_threads, hw_cpu_num;
1160 int propsize;
1161 extern void __secondary_hold(void);
1162 extern unsigned long __secondary_hold_spinloop;
1163 extern unsigned long __secondary_hold_acknowledge;
1164 unsigned long *spinloop
1165 = (void *) __pa(&__secondary_hold_spinloop);
1166 unsigned long *acknowledge
1167 = (void *) __pa(&__secondary_hold_acknowledge);
1168#ifdef CONFIG_PPC64
1169 unsigned long secondary_hold
1170 = __pa(*PTRRELOC((unsigned long *)__secondary_hold));
1171#else
1172 unsigned long secondary_hold = __pa(&__secondary_hold);
1173#endif
1174 struct prom_t *_prom = &RELOC(prom);
1175
1176 prom_debug("prom_hold_cpus: start...\n");
1177 prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop);
1178 prom_debug(" 1) *spinloop = 0x%x\n", *spinloop);
1179 prom_debug(" 1) acknowledge = 0x%x\n",
1180 (unsigned long)acknowledge);
1181 prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge);
1182 prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold);
1183
1184 /* Set the common spinloop variable, so all of the secondary cpus
1185 * will block when they are awakened from their OF spinloop.
1186 * This must occur for both SMP and non SMP kernels, since OF will
1187 * be trashed when we move the kernel.
1188 */
1189 *spinloop = 0;
1190
1191#ifdef CONFIG_HMT
1192 for (i = 0; i < NR_CPUS; i++) {
1193 RELOC(hmt_thread_data)[i].pir = 0xdeadbeef;
1194 }
1195#endif
1196 /* look for cpus */
1197 for (node = 0; prom_next_node(&node); ) {
1198 type[0] = 0;
1199 prom_getprop(node, "device_type", type, sizeof(type));
1200 if (strcmp(type, RELOC("cpu")) != 0)
1201 continue;
1202
1203 /* Skip non-configured cpus. */
1204 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1205 if (strcmp(type, RELOC("okay")) != 0)
1206 continue;
1207
1208 reg = -1;
1209 prom_getprop(node, "reg", &reg, sizeof(reg));
1210
1211 prom_debug("\ncpuid = 0x%x\n", cpuid);
1212 prom_debug("cpu hw idx = 0x%x\n", reg);
1213
1214 /* Init the acknowledge var which will be reset by
1215 * the secondary cpu when it awakens from its OF
1216 * spinloop.
1217 */
1218 *acknowledge = (unsigned long)-1;
1219
1220 propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s",
1221 &interrupt_server,
1222 sizeof(interrupt_server));
1223 if (propsize < 0) {
1224 /* no property. old hardware has no SMT */
1225 cpu_threads = 1;
1226 interrupt_server[0] = reg; /* fake it with phys id */
1227 } else {
1228 /* We have a threaded processor */
1229 cpu_threads = propsize / sizeof(u32);
1230 if (cpu_threads > MAX_CPU_THREADS) {
1231 prom_printf("SMT: too many threads!\n"
1232 "SMT: found %x, max is %x\n",
1233 cpu_threads, MAX_CPU_THREADS);
1234 cpu_threads = 1; /* ToDo: panic? */
1235 }
1236 }
1237
1238 hw_cpu_num = interrupt_server[0];
1239 if (hw_cpu_num != _prom->cpu) {
1240 /* Primary Thread of non-boot cpu */
1241 prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg);
1242 call_prom("start-cpu", 3, 0, node,
1243 secondary_hold, reg);
1244
1245 for ( i = 0 ; (i < 100000000) &&
1246 (*acknowledge == ((unsigned long)-1)); i++ )
1247 mb();
1248
1249 if (*acknowledge == reg) {
1250 prom_printf("done\n");
1251 /* We have to get every CPU out of OF,
1252 * even if we never start it. */
1253 if (cpuid >= NR_CPUS)
1254 goto next;
1255 } else {
1256 prom_printf("failed: %x\n", *acknowledge);
1257 }
1258 }
1259#ifdef CONFIG_SMP
1260 else
1261 prom_printf("%x : boot cpu %x\n", cpuid, reg);
1262#endif
1263next:
1264#ifdef CONFIG_SMP
1265 /* Init paca for secondary threads. They start later. */
1266 for (i=1; i < cpu_threads; i++) {
1267 cpuid++;
1268 if (cpuid >= NR_CPUS)
1269 continue;
1270 }
1271#endif /* CONFIG_SMP */
1272 cpuid++;
1273 }
1274#ifdef CONFIG_HMT
1275 /* Only enable HMT on processors that provide support. */
1276 if (__is_processor(PV_PULSAR) ||
1277 __is_processor(PV_ICESTAR) ||
1278 __is_processor(PV_SSTAR)) {
1279 prom_printf(" starting secondary threads\n");
1280
1281 for (i = 0; i < NR_CPUS; i += 2) {
1282 if (!cpu_online(i))
1283 continue;
1284
1285 if (i == 0) {
1286 unsigned long pir = mfspr(SPRN_PIR);
1287 if (__is_processor(PV_PULSAR)) {
1288 RELOC(hmt_thread_data)[i].pir =
1289 pir & 0x1f;
1290 } else {
1291 RELOC(hmt_thread_data)[i].pir =
1292 pir & 0x3ff;
1293 }
1294 }
1295 }
1296 } else {
1297 prom_printf("Processor is not HMT capable\n");
1298 }
1299#endif
1300
1301 if (cpuid > NR_CPUS)
1302 prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS)
1303 ") exceeded: ignoring extras\n");
1304
1305 prom_debug("prom_hold_cpus: end...\n");
1306#endif
1307}
1308
1309
1310static void __init prom_init_client_services(unsigned long pp)
1311{
1312 struct prom_t *_prom = &RELOC(prom);
1313
1314 /* Get a handle to the prom entry point before anything else */
1315 RELOC(prom_entry) = pp;
1316
1317 /* get a handle for the stdout device */
1318 _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
1319 if (!PHANDLE_VALID(_prom->chosen))
1320 prom_panic("cannot find chosen"); /* msg won't be printed :( */
1321
1322 /* get device tree root */
1323 _prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
1324 if (!PHANDLE_VALID(_prom->root))
1325 prom_panic("cannot find device tree root"); /* msg won't be printed :( */
1326}
1327
1328static void __init prom_init_stdout(void)
1329{
1330 struct prom_t *_prom = &RELOC(prom);
1331 char *path = RELOC(of_stdout_device);
1332 char type[16];
1333 u32 val;
1334
1335 if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)
1336 prom_panic("cannot find stdout");
1337
1338 _prom->stdout = val;
1339
1340 /* Get the full OF pathname of the stdout device */
1341 memset(path, 0, 256);
1342 call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
1343 val = call_prom("instance-to-package", 1, 1, _prom->stdout);
1344 prom_setprop(_prom->chosen, "linux,stdout-package", &val, sizeof(val));
1345 prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
1346 prom_setprop(_prom->chosen, "linux,stdout-path",
1347 RELOC(of_stdout_device), strlen(RELOC(of_stdout_device))+1);
1348
1349 /* If it's a display, note it */
1350 memset(type, 0, sizeof(type));
1351 prom_getprop(val, "device_type", type, sizeof(type));
1352 if (strcmp(type, RELOC("display")) == 0)
1353 prom_setprop(val, "linux,boot-display", NULL, 0);
1354}
1355
1356static void __init prom_close_stdin(void)
1357{
1358 struct prom_t *_prom = &RELOC(prom);
1359 ihandle val;
1360
1361 if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
1362 call_prom("close", 1, 0, val);
1363}
1364
1365static int __init prom_find_machine_type(void)
1366{
1367 struct prom_t *_prom = &RELOC(prom);
1368 char compat[256];
1369 int len, i = 0;
1370 phandle rtas;
1371
1372 len = prom_getprop(_prom->root, "compatible",
1373 compat, sizeof(compat)-1);
1374 if (len > 0) {
1375 compat[len] = 0;
1376 while (i < len) {
1377 char *p = &compat[i];
1378 int sl = strlen(p);
1379 if (sl == 0)
1380 break;
1381 if (strstr(p, RELOC("Power Macintosh")) ||
1382 strstr(p, RELOC("MacRISC4")))
1383 return PLATFORM_POWERMAC;
1384#ifdef CONFIG_PPC64
1385 if (strstr(p, RELOC("Momentum,Maple")))
1386 return PLATFORM_MAPLE;
1387#endif
1388 i += sl + 1;
1389 }
1390 }
1391#ifdef CONFIG_PPC64
1392 /* Default to pSeries. We need to know if we are running LPAR */
1393 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1394 if (PHANDLE_VALID(rtas)) {
1395 int x = prom_getproplen(rtas, "ibm,hypertas-functions");
1396 if (x != PROM_ERROR) {
1397 prom_printf("Hypertas detected, assuming LPAR !\n");
1398 return PLATFORM_PSERIES_LPAR;
1399 }
1400 }
1401 return PLATFORM_PSERIES;
1402#else
1403 return PLATFORM_CHRP;
1404#endif
1405}
1406
1407static int __init setup_disp(phandle dp)
1408{
1409#if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32)
1410 int width = 640, height = 480, depth = 8, pitch;
1411 unsigned address;
1412 u32 addrs[8][5];
1413 int i, naddrs;
1414 char name[32];
1415 char *getprop = "getprop";
1416
1417 prom_printf("Initializing screen: ");
1418
1419 memset(name, 0, sizeof(name));
1420 call_prom(getprop, 4, 1, dp, "name", name, sizeof(name));
1421 name[sizeof(name)-1] = 0;
1422 prom_print(name);
1423 prom_print("\n");
1424 call_prom(getprop, 4, 1, dp, "width", &width, sizeof(width));
1425 call_prom(getprop, 4, 1, dp, "height", &height, sizeof(height));
1426 call_prom(getprop, 4, 1, dp, "depth", &depth, sizeof(depth));
1427 pitch = width * ((depth + 7) / 8);
1428 call_prom(getprop, 4, 1, dp, "linebytes",
1429 &pitch, sizeof(pitch));
1430 if (pitch == 1)
1431 pitch = 0x1000; /* for strange IBM display */
1432 address = 0;
1433 call_prom(getprop, 4, 1, dp, "address", &address, sizeof(address));
1434 if (address == 0) {
1435 /* look for an assigned address with a size of >= 1MB */
1436 naddrs = call_prom(getprop, 4, 1, dp, "assigned-addresses",
1437 addrs, sizeof(addrs));
1438 naddrs /= 20;
1439 for (i = 0; i < naddrs; ++i) {
1440 if (addrs[i][4] >= (1 << 20)) {
1441 address = addrs[i][2];
1442 /* use the BE aperture if possible */
1443 if (addrs[i][4] >= (16 << 20))
1444 address += (8 << 20);
1445 break;
1446 }
1447 }
1448 if (address == 0) {
1449 prom_print("Failed to get address\n");
1450 return 0;
1451 }
1452 }
1453 /* kludge for valkyrie */
1454 if (strcmp(name, "valkyrie") == 0)
1455 address += 0x1000;
1456
1457 prom_printf("\n\n\n\naddress = %x\n", address);
1458 btext_setup_display(width, height, depth, pitch, address);
1459#endif /* CONFIG_BOOTX_TEXT && CONFIG_PPC32 */
1460 return 1;
1461}
1462
1463static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
1464{
1465 return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
1466}
1467
1468/*
1469 * If we have a display that we don't know how to drive,
1470 * we will want to try to execute OF's open method for it
1471 * later. However, OF will probably fall over if we do that
1472 * we've taken over the MMU.
1473 * So we check whether we will need to open the display,
1474 * and if so, open it now.
1475 */
1476static void __init prom_check_displays(void)
1477{
1478 char type[16], *path;
1479 phandle node;
1480 ihandle ih;
1481 int i;
1482 int got_display = 0;
1483
1484 static unsigned char default_colors[] = {
1485 0x00, 0x00, 0x00,
1486 0x00, 0x00, 0xaa,
1487 0x00, 0xaa, 0x00,
1488 0x00, 0xaa, 0xaa,
1489 0xaa, 0x00, 0x00,
1490 0xaa, 0x00, 0xaa,
1491 0xaa, 0xaa, 0x00,
1492 0xaa, 0xaa, 0xaa,
1493 0x55, 0x55, 0x55,
1494 0x55, 0x55, 0xff,
1495 0x55, 0xff, 0x55,
1496 0x55, 0xff, 0xff,
1497 0xff, 0x55, 0x55,
1498 0xff, 0x55, 0xff,
1499 0xff, 0xff, 0x55,
1500 0xff, 0xff, 0xff
1501 };
1502 const unsigned char *clut;
1503
1504 prom_printf("Looking for displays\n");
1505 for (node = 0; prom_next_node(&node); ) {
1506 memset(type, 0, sizeof(type));
1507 prom_getprop(node, "device_type", type, sizeof(type));
1508 if (strcmp(type, RELOC("display")) != 0)
1509 continue;
1510
1511 /* It seems OF doesn't null-terminate the path :-( */
1512 path = RELOC(prom_scratch);
1513 memset(path, 0, PROM_SCRATCH_SIZE);
1514
1515 /*
1516 * leave some room at the end of the path for appending extra
1517 * arguments
1518 */
1519 if (call_prom("package-to-path", 3, 1, node, path,
1520 PROM_SCRATCH_SIZE-10) == PROM_ERROR)
1521 continue;
1522 prom_printf("found display : %s, opening ... ", path);
1523
1524 ih = call_prom("open", 1, 1, path);
1525 if (ih == 0) {
1526 prom_printf("failed\n");
1527 continue;
1528 }
1529
1530 /* Success */
1531 prom_printf("done\n");
1532 prom_setprop(node, "linux,opened", NULL, 0);
1533
1534 /* Setup a usable color table when the appropriate
1535 * method is available. Should update this to set-colors */
1536 clut = RELOC(default_colors);
1537 for (i = 0; i < 32; i++, clut += 3)
1538 if (prom_set_color(ih, i, clut[0], clut[1],
1539 clut[2]) != 0)
1540 break;
1541
1542#ifdef CONFIG_LOGO_LINUX_CLUT224
1543 clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
1544 for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
1545 if (prom_set_color(ih, i + 32, clut[0], clut[1],
1546 clut[2]) != 0)
1547 break;
1548#endif /* CONFIG_LOGO_LINUX_CLUT224 */
1549 if (!got_display)
1550 got_display = setup_disp(node);
1551 }
1552}
1553
1554
1555/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
1556static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
1557 unsigned long needed, unsigned long align)
1558{
1559 void *ret;
1560
1561 *mem_start = _ALIGN(*mem_start, align);
1562 while ((*mem_start + needed) > *mem_end) {
1563 unsigned long room, chunk;
1564
1565 prom_debug("Chunk exhausted, claiming more at %x...\n",
1566 RELOC(alloc_bottom));
1567 room = RELOC(alloc_top) - RELOC(alloc_bottom);
1568 if (room > DEVTREE_CHUNK_SIZE)
1569 room = DEVTREE_CHUNK_SIZE;
1570 if (room < PAGE_SIZE)
1571 prom_panic("No memory for flatten_device_tree (no room)");
1572 chunk = alloc_up(room, 0);
1573 if (chunk == 0)
1574 prom_panic("No memory for flatten_device_tree (claim failed)");
1575 *mem_end = RELOC(alloc_top);
1576 }
1577
1578 ret = (void *)*mem_start;
1579 *mem_start += needed;
1580
1581 return ret;
1582}
1583
1584#define dt_push_token(token, mem_start, mem_end) \
1585 do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)
1586
1587static unsigned long __init dt_find_string(char *str)
1588{
1589 char *s, *os;
1590
1591 s = os = (char *)RELOC(dt_string_start);
1592 s += 4;
1593 while (s < (char *)RELOC(dt_string_end)) {
1594 if (strcmp(s, str) == 0)
1595 return s - os;
1596 s += strlen(s) + 1;
1597 }
1598 return 0;
1599}
1600
1601/*
1602 * The Open Firmware 1275 specification states properties must be 31 bytes or
1603 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
1604 */
1605#define MAX_PROPERTY_NAME 64
1606
1607static void __init scan_dt_build_strings(phandle node,
1608 unsigned long *mem_start,
1609 unsigned long *mem_end)
1610{
1611 char *prev_name, *namep, *sstart;
1612 unsigned long soff;
1613 phandle child;
1614
1615 sstart = (char *)RELOC(dt_string_start);
1616
1617 /* get and store all property names */
1618 prev_name = RELOC("");
1619 for (;;) {
1620 /* 64 is max len of name including nul. */
1621 namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
1622 if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
1623 /* No more nodes: unwind alloc */
1624 *mem_start = (unsigned long)namep;
1625 break;
1626 }
1627
1628 /* skip "name" */
1629 if (strcmp(namep, RELOC("name")) == 0) {
1630 *mem_start = (unsigned long)namep;
1631 prev_name = RELOC("name");
1632 continue;
1633 }
1634 /* get/create string entry */
1635 soff = dt_find_string(namep);
1636 if (soff != 0) {
1637 *mem_start = (unsigned long)namep;
1638 namep = sstart + soff;
1639 } else {
1640 /* Trim off some if we can */
1641 *mem_start = (unsigned long)namep + strlen(namep) + 1;
1642 RELOC(dt_string_end) = *mem_start;
1643 }
1644 prev_name = namep;
1645 }
1646
1647 /* do all our children */
1648 child = call_prom("child", 1, 1, node);
1649 while (child != 0) {
1650 scan_dt_build_strings(child, mem_start, mem_end);
1651 child = call_prom("peer", 1, 1, child);
1652 }
1653}
1654
1655static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1656 unsigned long *mem_end)
1657{
1658 phandle child;
1659 char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
1660 unsigned long soff;
1661 unsigned char *valp;
1662 static char pname[MAX_PROPERTY_NAME];
1663 int l;
1664
1665 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
1666
1667 /* get the node's full name */
1668 namep = (char *)*mem_start;
1669 l = call_prom("package-to-path", 3, 1, node,
1670 namep, *mem_end - *mem_start);
1671 if (l >= 0) {
1672 /* Didn't fit? Get more room. */
1673 if ((l+1) > (*mem_end - *mem_start)) {
1674 namep = make_room(mem_start, mem_end, l+1, 1);
1675 call_prom("package-to-path", 3, 1, node, namep, l);
1676 }
1677 namep[l] = '\0';
1678
1679 /* Fixup an Apple bug where they have bogus \0 chars in the
1680 * middle of the path in some properties
1681 */
1682 for (p = namep, ep = namep + l; p < ep; p++)
1683 if (*p == '\0') {
1684 memmove(p, p+1, ep - p);
1685 ep--; l--; p--;
1686 }
1687
1688 /* now try to extract the unit name in that mess */
1689 for (p = namep, lp = NULL; *p; p++)
1690 if (*p == '/')
1691 lp = p + 1;
1692 if (lp != NULL)
1693 memmove(namep, lp, strlen(lp) + 1);
1694 *mem_start = _ALIGN(((unsigned long) namep) +
1695 strlen(namep) + 1, 4);
1696 }
1697
1698 /* get it again for debugging */
1699 path = RELOC(prom_scratch);
1700 memset(path, 0, PROM_SCRATCH_SIZE);
1701 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1702
1703 /* get and store all properties */
1704 prev_name = RELOC("");
1705 sstart = (char *)RELOC(dt_string_start);
1706 for (;;) {
1707 if (call_prom("nextprop", 3, 1, node, prev_name,
1708 RELOC(pname)) != 1)
1709 break;
1710
1711 /* skip "name" */
1712 if (strcmp(RELOC(pname), RELOC("name")) == 0) {
1713 prev_name = RELOC("name");
1714 continue;
1715 }
1716
1717 /* find string offset */
1718 soff = dt_find_string(RELOC(pname));
1719 if (soff == 0) {
1720 prom_printf("WARNING: Can't find string index for"
1721 " <%s>, node %s\n", RELOC(pname), path);
1722 break;
1723 }
1724 prev_name = sstart + soff;
1725
1726 /* get length */
1727 l = call_prom("getproplen", 2, 1, node, RELOC(pname));
1728
1729 /* sanity checks */
1730 if (l == PROM_ERROR)
1731 continue;
1732 if (l > MAX_PROPERTY_LENGTH) {
1733 prom_printf("WARNING: ignoring large property ");
1734 /* It seems OF doesn't null-terminate the path :-( */
1735 prom_printf("[%s] ", path);
1736 prom_printf("%s length 0x%x\n", RELOC(pname), l);
1737 continue;
1738 }
1739
1740 /* push property head */
1741 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1742 dt_push_token(l, mem_start, mem_end);
1743 dt_push_token(soff, mem_start, mem_end);
1744
1745 /* push property content */
1746 valp = make_room(mem_start, mem_end, l, 4);
1747 call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
1748 *mem_start = _ALIGN(*mem_start, 4);
1749 }
1750
1751 /* Add a "linux,phandle" property. */
1752 soff = dt_find_string(RELOC("linux,phandle"));
1753 if (soff == 0)
1754 prom_printf("WARNING: Can't find string index for"
1755 " <linux-phandle> node %s\n", path);
1756 else {
1757 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1758 dt_push_token(4, mem_start, mem_end);
1759 dt_push_token(soff, mem_start, mem_end);
1760 valp = make_room(mem_start, mem_end, 4, 4);
1761 *(u32 *)valp = node;
1762 }
1763
1764 /* do all our children */
1765 child = call_prom("child", 1, 1, node);
1766 while (child != 0) {
1767 scan_dt_build_struct(child, mem_start, mem_end);
1768 child = call_prom("peer", 1, 1, child);
1769 }
1770
1771 dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
1772}
1773
1774static void __init flatten_device_tree(void)
1775{
1776 phandle root;
1777 unsigned long mem_start, mem_end, room;
1778 struct boot_param_header *hdr;
1779 struct prom_t *_prom = &RELOC(prom);
1780 char *namep;
1781 u64 *rsvmap;
1782
1783 /*
1784 * Check how much room we have between alloc top & bottom (+/- a
1785 * few pages), crop to 4Mb, as this is our "chuck" size
1786 */
1787 room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000;
1788 if (room > DEVTREE_CHUNK_SIZE)
1789 room = DEVTREE_CHUNK_SIZE;
1790 prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom));
1791
1792 /* Now try to claim that */
1793 mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
1794 if (mem_start == 0)
1795 prom_panic("Can't allocate initial device-tree chunk\n");
1796 mem_end = RELOC(alloc_top);
1797
1798 /* Get root of tree */
1799 root = call_prom("peer", 1, 1, (phandle)0);
1800 if (root == (phandle)0)
1801 prom_panic ("couldn't get device tree root\n");
1802
1803 /* Build header and make room for mem rsv map */
1804 mem_start = _ALIGN(mem_start, 4);
1805 hdr = make_room(&mem_start, &mem_end,
1806 sizeof(struct boot_param_header), 4);
1807 RELOC(dt_header_start) = (unsigned long)hdr;
1808 rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
1809
1810 /* Start of strings */
1811 mem_start = PAGE_ALIGN(mem_start);
1812 RELOC(dt_string_start) = mem_start;
1813 mem_start += 4; /* hole */
1814
1815 /* Add "linux,phandle" in there, we'll need it */
1816 namep = make_room(&mem_start, &mem_end, 16, 1);
1817 strcpy(namep, RELOC("linux,phandle"));
1818 mem_start = (unsigned long)namep + strlen(namep) + 1;
1819
1820 /* Build string array */
1821 prom_printf("Building dt strings...\n");
1822 scan_dt_build_strings(root, &mem_start, &mem_end);
1823 RELOC(dt_string_end) = mem_start;
1824
1825 /* Build structure */
1826 mem_start = PAGE_ALIGN(mem_start);
1827 RELOC(dt_struct_start) = mem_start;
1828 prom_printf("Building dt structure...\n");
1829 scan_dt_build_struct(root, &mem_start, &mem_end);
1830 dt_push_token(OF_DT_END, &mem_start, &mem_end);
1831 RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
1832
1833 /* Finish header */
1834 hdr->boot_cpuid_phys = _prom->cpu;
1835 hdr->magic = OF_DT_HEADER;
1836 hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
1837 hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
1838 hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start);
1839 hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start);
1840 hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start);
1841 hdr->version = OF_DT_VERSION;
1842 /* Version 16 is not backward compatible */
1843 hdr->last_comp_version = 0x10;
1844
1845 /* Reserve the whole thing and copy the reserve map in, we
1846 * also bump mem_reserve_cnt to cause further reservations to
1847 * fail since it's too late.
1848 */
1849 reserve_mem(RELOC(dt_header_start), hdr->totalsize);
1850 memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
1851
1852#ifdef DEBUG_PROM
1853 {
1854 int i;
1855 prom_printf("reserved memory map:\n");
1856 for (i = 0; i < RELOC(mem_reserve_cnt); i++)
1857 prom_printf(" %x - %x\n",
1858 RELOC(mem_reserve_map)[i].base,
1859 RELOC(mem_reserve_map)[i].size);
1860 }
1861#endif
1862 RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
1863
1864 prom_printf("Device tree strings 0x%x -> 0x%x\n",
1865 RELOC(dt_string_start), RELOC(dt_string_end));
1866 prom_printf("Device tree struct 0x%x -> 0x%x\n",
1867 RELOC(dt_struct_start), RELOC(dt_struct_end));
1868
1869}
1870
1871
1872static void __init fixup_device_tree(void)
1873{
1874#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
1875 phandle u3, i2c, mpic;
1876 u32 u3_rev;
1877 u32 interrupts[2];
1878 u32 parent;
1879
1880 /* Some G5s have a missing interrupt definition, fix it up here */
1881 u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
1882 if (!PHANDLE_VALID(u3))
1883 return;
1884 i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
1885 if (!PHANDLE_VALID(i2c))
1886 return;
1887 mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
1888 if (!PHANDLE_VALID(mpic))
1889 return;
1890
1891 /* check if proper rev of u3 */
1892 if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
1893 == PROM_ERROR)
1894 return;
1895 if (u3_rev != 0x35 && u3_rev != 0x37)
1896 return;
1897 /* does it need fixup ? */
1898 if (prom_getproplen(i2c, "interrupts") > 0)
1899 return;
1900
1901 prom_printf("fixing up bogus interrupts for u3 i2c...\n");
1902
1903 /* interrupt on this revision of u3 is number 0 and level */
1904 interrupts[0] = 0;
1905 interrupts[1] = 1;
1906 prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts));
1907 parent = (u32)mpic;
1908 prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent));
1909#endif
1910}
1911
1912
1913static void __init prom_find_boot_cpu(void)
1914{
1915 struct prom_t *_prom = &RELOC(prom);
1916 u32 getprop_rval;
1917 ihandle prom_cpu;
1918 phandle cpu_pkg;
1919
1920 if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0)
1921 prom_panic("cannot find boot cpu");
1922
1923 cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
1924
1925 prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
1926 _prom->cpu = getprop_rval;
1927
1928 prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu);
1929}
1930
1931static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
1932{
1933#ifdef CONFIG_BLK_DEV_INITRD
1934 struct prom_t *_prom = &RELOC(prom);
1935
1936 if (r3 && r4 && r4 != 0xdeadbeef) {
1937 unsigned long val;
1938
1939 RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3;
1940 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
1941
1942 val = RELOC(prom_initrd_start);
1943 prom_setprop(_prom->chosen, "linux,initrd-start", &val,
1944 sizeof(val));
1945 val = RELOC(prom_initrd_end);
1946 prom_setprop(_prom->chosen, "linux,initrd-end", &val,
1947 sizeof(val));
1948
1949 reserve_mem(RELOC(prom_initrd_start),
1950 RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
1951
1952 prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start));
1953 prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end));
1954 }
1955#endif /* CONFIG_BLK_DEV_INITRD */
1956}
1957
1958/*
1959 * We enter here early on, when the Open Firmware prom is still
1960 * handling exceptions and the MMU hash table for us.
1961 */
1962
1963unsigned long __init prom_init(unsigned long r3, unsigned long r4,
1964 unsigned long pp,
1965 unsigned long r6, unsigned long r7)
1966{
1967 struct prom_t *_prom;
1968 extern char _stext[];
1969 unsigned long hdr;
1970 u32 getprop_rval;
1971
1972#ifdef CONFIG_PPC32
1973 unsigned long offset = reloc_offset();
1974 reloc_got2(offset);
1975#endif
1976
1977 _prom = &RELOC(prom);
1978
1979 /*
1980 * First zero the BSS
1981 */
1982 memset(&RELOC(__bss_start), 0, __bss_stop - __bss_start);
1983
1984 /*
1985 * Init interface to Open Firmware, get some node references,
1986 * like /chosen
1987 */
1988 prom_init_client_services(pp);
1989
1990 /*
1991 * Init prom stdout device
1992 */
1993 prom_init_stdout();
1994
1995 /*
1996 * Check for an initrd
1997 */
1998 prom_check_initrd(r3, r4);
1999
2000 /*
2001 * Get default machine type. At this point, we do not differentiate
2002 * between pSeries SMP and pSeries LPAR
2003 */
2004 RELOC(of_platform) = prom_find_machine_type();
2005 getprop_rval = RELOC(of_platform);
2006 prom_setprop(_prom->chosen, "linux,platform",
2007 &getprop_rval, sizeof(getprop_rval));
2008
2009#ifdef CONFIG_PPC_PSERIES
2010 /*
2011 * On pSeries, inform the firmware about our capabilities
2012 */
2013 if (RELOC(of_platform) & PLATFORM_PSERIES)
2014 prom_send_capabilities();
2015#endif
2016
2017#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_BPA)
2018 /*
2019 * On pSeries and BPA, copy the CPU hold code
2020 */
2021 if (RELOC(of_platform) & (PLATFORM_PSERIES | PLATFORM_BPA))
2022 copy_and_flush(0, KERNELBASE - offset, 0x100, 0);
2023#endif
2024
2025 /*
2026 * Do early parsing of command line
2027 */
2028 early_cmdline_parse();
2029
2030 /*
2031 * Initialize memory management within prom_init
2032 */
2033 prom_init_mem();
2034
2035 /*
2036 * Determine which cpu is actually running right _now_
2037 */
2038 prom_find_boot_cpu();
2039
2040 /*
2041 * Initialize display devices
2042 */
2043 prom_check_displays();
2044
2045#ifdef CONFIG_PPC64
2046 /*
2047 * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
2048 * that uses the allocator, we need to make sure we get the top of memory
2049 * available for us here...
2050 */
2051 if (RELOC(of_platform) == PLATFORM_PSERIES)
2052 prom_initialize_tce_table();
2053#endif
2054
2055 /*
2056 * On non-powermacs, try to instantiate RTAS and puts all CPUs
2057 * in spin-loops. PowerMacs don't have a working RTAS and use
2058 * a different way to spin CPUs
2059 */
2060 if (RELOC(of_platform) != PLATFORM_POWERMAC) {
2061 prom_instantiate_rtas();
2062 prom_hold_cpus();
2063 }
2064
2065 /*
2066 * Fill in some infos for use by the kernel later on
2067 */
2068 if (RELOC(prom_memory_limit))
2069 prom_setprop(_prom->chosen, "linux,memory-limit",
2070 &RELOC(prom_memory_limit),
2071 sizeof(prom_memory_limit));
2072#ifdef CONFIG_PPC64
2073 if (RELOC(ppc64_iommu_off))
2074 prom_setprop(_prom->chosen, "linux,iommu-off", NULL, 0);
2075
2076 if (RELOC(iommu_force_on))
2077 prom_setprop(_prom->chosen, "linux,iommu-force-on", NULL, 0);
2078
2079 if (RELOC(prom_tce_alloc_start)) {
2080 prom_setprop(_prom->chosen, "linux,tce-alloc-start",
2081 &RELOC(prom_tce_alloc_start),
2082 sizeof(prom_tce_alloc_start));
2083 prom_setprop(_prom->chosen, "linux,tce-alloc-end",
2084 &RELOC(prom_tce_alloc_end),
2085 sizeof(prom_tce_alloc_end));
2086 }
2087#endif
2088
2089 /*
2090 * Fixup any known bugs in the device-tree
2091 */
2092 fixup_device_tree();
2093
2094 /*
2095 * Now finally create the flattened device-tree
2096 */
2097 prom_printf("copying OF device tree ...\n");
2098 flatten_device_tree();
2099
2100 /* in case stdin is USB and still active on IBM machines... */
2101 prom_close_stdin();
2102
2103 /*
2104 * Call OF "quiesce" method to shut down pending DMA's from
2105 * devices etc...
2106 */
2107 prom_printf("Calling quiesce ...\n");
2108 call_prom("quiesce", 0, 0);
2109
2110 /*
2111 * And finally, call the kernel passing it the flattened device
2112 * tree and NULL as r5, thus triggering the new entry point which
2113 * is common to us and kexec
2114 */
2115 hdr = RELOC(dt_header_start);
2116 prom_printf("returning from prom_init\n");
2117 prom_debug("->dt_header_start=0x%x\n", hdr);
2118
2119#ifdef CONFIG_PPC32
2120 reloc_got2(-offset);
2121#endif
2122
2123 __start(hdr, 0, 0);
2124
2125 return 0;
2126}
diff --git a/arch/powerpc/kernel/setup.c b/arch/powerpc/kernel/setup.c
new file mode 100644
index 000000000000..27d7f828212b
--- /dev/null
+++ b/arch/powerpc/kernel/setup.c
@@ -0,0 +1,678 @@
1/*
2 * Common prep/pmac/chrp boot and setup code.
3 */
4
5#include <linux/config.h>
6#include <linux/module.h>
7#include <linux/string.h>
8#include <linux/sched.h>
9#include <linux/init.h>
10#include <linux/kernel.h>
11#include <linux/reboot.h>
12#include <linux/delay.h>
13#include <linux/initrd.h>
14#include <linux/ide.h>
15#include <linux/tty.h>
16#include <linux/bootmem.h>
17#include <linux/seq_file.h>
18#include <linux/root_dev.h>
19#include <linux/cpu.h>
20#include <linux/console.h>
21
22#include <asm/residual.h>
23#include <asm/io.h>
24#include <asm/prom.h>
25#include <asm/processor.h>
26#include <asm/pgtable.h>
27#include <asm/bootinfo.h>
28#include <asm/setup.h>
29#include <asm/amigappc.h>
30#include <asm/smp.h>
31#include <asm/elf.h>
32#include <asm/cputable.h>
33#include <asm/bootx.h>
34#include <asm/btext.h>
35#include <asm/machdep.h>
36#include <asm/uaccess.h>
37#include <asm/system.h>
38#include <asm/pmac_feature.h>
39#include <asm/sections.h>
40#include <asm/nvram.h>
41#include <asm/xmon.h>
42#include <asm/ocp.h>
43
44#define USES_PPC_SYS (defined(CONFIG_85xx) || defined(CONFIG_83xx) || \
45 defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \
46 defined(CONFIG_PPC_MPC52xx))
47
48#if USES_PPC_SYS
49#include <asm/ppc_sys.h>
50#endif
51
52#if defined CONFIG_KGDB
53#include <asm/kgdb.h>
54#endif
55
56extern void platform_init(void);
57extern void bootx_init(unsigned long r4, unsigned long phys);
58
59extern void ppc6xx_idle(void);
60extern void power4_idle(void);
61
62boot_infos_t *boot_infos;
63struct ide_machdep_calls ppc_ide_md;
64
65/* Used with the BI_MEMSIZE bootinfo parameter to store the memory
66 size value reported by the boot loader. */
67unsigned long boot_mem_size;
68
69unsigned long ISA_DMA_THRESHOLD;
70unsigned int DMA_MODE_READ;
71unsigned int DMA_MODE_WRITE;
72
73#ifdef CONFIG_PPC_MULTIPLATFORM
74int _machine = 0;
75
76extern void prep_init(void);
77extern void pmac_init(void);
78extern void chrp_init(void);
79
80dev_t boot_dev;
81#endif /* CONFIG_PPC_MULTIPLATFORM */
82
83#ifdef CONFIG_MAGIC_SYSRQ
84unsigned long SYSRQ_KEY = 0x54;
85#endif /* CONFIG_MAGIC_SYSRQ */
86
87#ifdef CONFIG_VGA_CONSOLE
88unsigned long vgacon_remap_base;
89#endif
90
91struct machdep_calls ppc_md;
92
93/*
94 * These are used in binfmt_elf.c to put aux entries on the stack
95 * for each elf executable being started.
96 */
97int dcache_bsize;
98int icache_bsize;
99int ucache_bsize;
100
101#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_FB_VGA16) || \
102 defined(CONFIG_FB_VGA16_MODULE) || defined(CONFIG_FB_VESA)
103struct screen_info screen_info = {
104 0, 25, /* orig-x, orig-y */
105 0, /* unused */
106 0, /* orig-video-page */
107 0, /* orig-video-mode */
108 80, /* orig-video-cols */
109 0,0,0, /* ega_ax, ega_bx, ega_cx */
110 25, /* orig-video-lines */
111 1, /* orig-video-isVGA */
112 16 /* orig-video-points */
113};
114#endif /* CONFIG_VGA_CONSOLE || CONFIG_FB_VGA16 || CONFIG_FB_VESA */
115
116void machine_restart(char *cmd)
117{
118#ifdef CONFIG_NVRAM
119 nvram_sync();
120#endif
121 ppc_md.restart(cmd);
122}
123
124void machine_power_off(void)
125{
126#ifdef CONFIG_NVRAM
127 nvram_sync();
128#endif
129 ppc_md.power_off();
130}
131
132void machine_halt(void)
133{
134#ifdef CONFIG_NVRAM
135 nvram_sync();
136#endif
137 ppc_md.halt();
138}
139
140void (*pm_power_off)(void) = machine_power_off;
141
142#ifdef CONFIG_TAU
143extern u32 cpu_temp(unsigned long cpu);
144extern u32 cpu_temp_both(unsigned long cpu);
145#endif /* CONFIG_TAU */
146
147int show_cpuinfo(struct seq_file *m, void *v)
148{
149 int i = (int) v - 1;
150 int err = 0;
151 unsigned int pvr;
152 unsigned short maj, min;
153 unsigned long lpj;
154
155 if (i >= NR_CPUS) {
156 /* Show summary information */
157#ifdef CONFIG_SMP
158 unsigned long bogosum = 0;
159 for (i = 0; i < NR_CPUS; ++i)
160 if (cpu_online(i))
161 bogosum += cpu_data[i].loops_per_jiffy;
162 seq_printf(m, "total bogomips\t: %lu.%02lu\n",
163 bogosum/(500000/HZ), bogosum/(5000/HZ) % 100);
164#endif /* CONFIG_SMP */
165
166 if (ppc_md.show_cpuinfo != NULL)
167 err = ppc_md.show_cpuinfo(m);
168 return err;
169 }
170
171#ifdef CONFIG_SMP
172 if (!cpu_online(i))
173 return 0;
174 pvr = cpu_data[i].pvr;
175 lpj = cpu_data[i].loops_per_jiffy;
176#else
177 pvr = mfspr(SPRN_PVR);
178 lpj = loops_per_jiffy;
179#endif
180
181 seq_printf(m, "processor\t: %d\n", i);
182 seq_printf(m, "cpu\t\t: ");
183
184 if (cur_cpu_spec->pvr_mask)
185 seq_printf(m, "%s", cur_cpu_spec->cpu_name);
186 else
187 seq_printf(m, "unknown (%08x)", pvr);
188#ifdef CONFIG_ALTIVEC
189 if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
190 seq_printf(m, ", altivec supported");
191#endif
192 seq_printf(m, "\n");
193
194#ifdef CONFIG_TAU
195 if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) {
196#ifdef CONFIG_TAU_AVERAGE
197 /* more straightforward, but potentially misleading */
198 seq_printf(m, "temperature \t: %u C (uncalibrated)\n",
199 cpu_temp(i));
200#else
201 /* show the actual temp sensor range */
202 u32 temp;
203 temp = cpu_temp_both(i);
204 seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n",
205 temp & 0xff, temp >> 16);
206#endif
207 }
208#endif /* CONFIG_TAU */
209
210 if (ppc_md.show_percpuinfo != NULL) {
211 err = ppc_md.show_percpuinfo(m, i);
212 if (err)
213 return err;
214 }
215
216 /* If we are a Freescale core do a simple check so
217 * we dont have to keep adding cases in the future */
218 if ((PVR_VER(pvr) & 0x8000) == 0x8000) {
219 maj = PVR_MAJ(pvr);
220 min = PVR_MIN(pvr);
221 } else {
222 switch (PVR_VER(pvr)) {
223 case 0x0020: /* 403 family */
224 maj = PVR_MAJ(pvr) + 1;
225 min = PVR_MIN(pvr);
226 break;
227 case 0x1008: /* 740P/750P ?? */
228 maj = ((pvr >> 8) & 0xFF) - 1;
229 min = pvr & 0xFF;
230 break;
231 default:
232 maj = (pvr >> 8) & 0xFF;
233 min = pvr & 0xFF;
234 break;
235 }
236 }
237
238 seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n",
239 maj, min, PVR_VER(pvr), PVR_REV(pvr));
240
241 seq_printf(m, "bogomips\t: %lu.%02lu\n",
242 lpj / (500000/HZ), (lpj / (5000/HZ)) % 100);
243
244#if USES_PPC_SYS
245 if (cur_ppc_sys_spec->ppc_sys_name)
246 seq_printf(m, "chipset\t\t: %s\n",
247 cur_ppc_sys_spec->ppc_sys_name);
248#endif
249
250#ifdef CONFIG_SMP
251 seq_printf(m, "\n");
252#endif
253
254 return 0;
255}
256
257static void *c_start(struct seq_file *m, loff_t *pos)
258{
259 int i = *pos;
260
261 return i <= NR_CPUS? (void *) (i + 1): NULL;
262}
263
264static void *c_next(struct seq_file *m, void *v, loff_t *pos)
265{
266 ++*pos;
267 return c_start(m, pos);
268}
269
270static void c_stop(struct seq_file *m, void *v)
271{
272}
273
274struct seq_operations cpuinfo_op = {
275 .start =c_start,
276 .next = c_next,
277 .stop = c_stop,
278 .show = show_cpuinfo,
279};
280
281/*
282 * We're called here very early in the boot. We determine the machine
283 * type and call the appropriate low-level setup functions.
284 * -- Cort <cort@fsmlabs.com>
285 *
286 * Note that the kernel may be running at an address which is different
287 * from the address that it was linked at, so we must use RELOC/PTRRELOC
288 * to access static data (including strings). -- paulus
289 */
290unsigned long __init early_init(unsigned long dt_ptr)
291{
292 unsigned long offset = reloc_offset();
293
294 reloc_got2(offset);
295
296 /*
297 * Identify the CPU type and fix up code sections
298 * that depend on which cpu we have.
299 */
300 identify_cpu(offset, 0);
301 do_cpu_ftr_fixups(offset);
302
303#ifdef CONFIG_BOOTX_TEXT
304 btext_prepare_BAT();
305#endif
306
307 reloc_got2(-offset);
308
309 return KERNELBASE + offset;
310}
311
312#ifdef CONFIG_PPC_OF
313/*
314 * Assume here that all clock rates are the same in a
315 * smp system. -- Cort
316 */
317int
318of_show_percpuinfo(struct seq_file *m, int i)
319{
320 struct device_node *cpu_node;
321 u32 *fp;
322 int s;
323
324 cpu_node = find_type_devices("cpu");
325 if (!cpu_node)
326 return 0;
327 for (s = 0; s < i && cpu_node->next; s++)
328 cpu_node = cpu_node->next;
329 fp = (u32 *)get_property(cpu_node, "clock-frequency", NULL);
330 if (fp)
331 seq_printf(m, "clock\t\t: %dMHz\n", *fp / 1000000);
332 return 0;
333}
334
335void __init
336intuit_machine_type(void)
337{
338 char *model;
339 struct device_node *root;
340
341 /* ask the OF info if we're a chrp or pmac */
342 root = find_path_device("/");
343 if (root != 0) {
344 /* assume pmac unless proven to be chrp -- Cort */
345 _machine = _MACH_Pmac;
346 model = get_property(root, "device_type", NULL);
347 if (model && !strncmp("chrp", model, 4))
348 _machine = _MACH_chrp;
349 else {
350 model = get_property(root, "model", NULL);
351 if (model && !strncmp(model, "IBM", 3))
352 _machine = _MACH_chrp;
353 }
354 }
355}
356#endif
357
358#ifdef CONFIG_PPC_MULTIPLATFORM
359/*
360 * The PPC_MULTIPLATFORM version of platform_init...
361 */
362void __init platform_init(void)
363{
364 /* if we didn't get any bootinfo telling us what we are... */
365 if (_machine == 0) {
366 /* prep boot loader tells us if we're prep or not */
367 if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
368 _machine = _MACH_prep;
369 }
370
371#ifdef CONFIG_PPC_PREP
372 /* not much more to do here, if prep */
373 if (_machine == _MACH_prep) {
374 prep_init();
375 return;
376 }
377#endif
378
379#ifdef CONFIG_ADB
380 if (strstr(cmd_line, "adb_sync")) {
381 extern int __adb_probe_sync;
382 __adb_probe_sync = 1;
383 }
384#endif /* CONFIG_ADB */
385
386 switch (_machine) {
387#ifdef CONFIG_PPC_PMAC
388 case _MACH_Pmac:
389 pmac_init();
390 break;
391#endif
392#ifdef CONFIG_PPC_CHRP
393 case _MACH_chrp:
394 chrp_init();
395 break;
396#endif
397 }
398}
399
400#ifdef CONFIG_SERIAL_CORE_CONSOLE
401extern char *of_stdout_device;
402
403static int __init set_preferred_console(void)
404{
405 struct device_node *prom_stdout;
406 char *name;
407 int offset = 0;
408
409 if (of_stdout_device == NULL)
410 return -ENODEV;
411
412 /* The user has requested a console so this is already set up. */
413 if (strstr(saved_command_line, "console="))
414 return -EBUSY;
415
416 prom_stdout = find_path_device(of_stdout_device);
417 if (!prom_stdout)
418 return -ENODEV;
419
420 name = (char *)get_property(prom_stdout, "name", NULL);
421 if (!name)
422 return -ENODEV;
423
424 if (strcmp(name, "serial") == 0) {
425 int i;
426 u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i);
427 if (i > 8) {
428 switch (reg[1]) {
429 case 0x3f8:
430 offset = 0;
431 break;
432 case 0x2f8:
433 offset = 1;
434 break;
435 case 0x898:
436 offset = 2;
437 break;
438 case 0x890:
439 offset = 3;
440 break;
441 default:
442 /* We dont recognise the serial port */
443 return -ENODEV;
444 }
445 }
446 } else if (strcmp(name, "ch-a") == 0)
447 offset = 0;
448 else if (strcmp(name, "ch-b") == 0)
449 offset = 1;
450 else
451 return -ENODEV;
452 return add_preferred_console("ttyS", offset, NULL);
453}
454console_initcall(set_preferred_console);
455#endif /* CONFIG_SERIAL_CORE_CONSOLE */
456#endif /* CONFIG_PPC_MULTIPLATFORM */
457
458struct bi_record *find_bootinfo(void)
459{
460 struct bi_record *rec;
461
462 rec = (struct bi_record *)_ALIGN((ulong)__bss_start+(1<<20)-1,(1<<20));
463 if ( rec->tag != BI_FIRST ) {
464 /*
465 * This 0x10000 offset is a terrible hack but it will go away when
466 * we have the bootloader handle all the relocation and
467 * prom calls -- Cort
468 */
469 rec = (struct bi_record *)_ALIGN((ulong)__bss_start+0x10000+(1<<20)-1,(1<<20));
470 if ( rec->tag != BI_FIRST )
471 return NULL;
472 }
473 return rec;
474}
475
476/*
477 * Find out what kind of machine we're on and save any data we need
478 * from the early boot process (devtree is copied on pmac by prom_init()).
479 * This is called very early on the boot process, after a minimal
480 * MMU environment has been set up but before MMU_init is called.
481 */
482void __init machine_init(unsigned long dt_ptr, unsigned long phys)
483{
484 early_init_devtree(__va(dt_ptr));
485
486#ifdef CONFIG_CMDLINE
487 strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
488#endif /* CONFIG_CMDLINE */
489
490#ifdef CONFIG_6xx
491 ppc_md.power_save = ppc6xx_idle;
492#endif
493#ifdef CONFIG_POWER4
494 ppc_md.power_save = power4_idle;
495#endif
496
497 platform_init();
498
499 if (ppc_md.progress)
500 ppc_md.progress("id mach(): done", 0x200);
501}
502
503#ifdef CONFIG_BOOKE_WDT
504/* Checks wdt=x and wdt_period=xx command-line option */
505int __init early_parse_wdt(char *p)
506{
507 if (p && strncmp(p, "0", 1) != 0)
508 booke_wdt_enabled = 1;
509
510 return 0;
511}
512early_param("wdt", early_parse_wdt);
513
514int __init early_parse_wdt_period (char *p)
515{
516 if (p)
517 booke_wdt_period = simple_strtoul(p, NULL, 0);
518
519 return 0;
520}
521early_param("wdt_period", early_parse_wdt_period);
522#endif /* CONFIG_BOOKE_WDT */
523
524/* Checks "l2cr=xxxx" command-line option */
525int __init ppc_setup_l2cr(char *str)
526{
527 if (cpu_has_feature(CPU_FTR_L2CR)) {
528 unsigned long val = simple_strtoul(str, NULL, 0);
529 printk(KERN_INFO "l2cr set to %lx\n", val);
530 _set_L2CR(0); /* force invalidate by disable cache */
531 _set_L2CR(val); /* and enable it */
532 }
533 return 1;
534}
535__setup("l2cr=", ppc_setup_l2cr);
536
537#ifdef CONFIG_GENERIC_NVRAM
538
539/* Generic nvram hooks used by drivers/char/gen_nvram.c */
540unsigned char nvram_read_byte(int addr)
541{
542 if (ppc_md.nvram_read_val)
543 return ppc_md.nvram_read_val(addr);
544 return 0xff;
545}
546EXPORT_SYMBOL(nvram_read_byte);
547
548void nvram_write_byte(unsigned char val, int addr)
549{
550 if (ppc_md.nvram_write_val)
551 ppc_md.nvram_write_val(addr, val);
552}
553EXPORT_SYMBOL(nvram_write_byte);
554
555void nvram_sync(void)
556{
557 if (ppc_md.nvram_sync)
558 ppc_md.nvram_sync();
559}
560EXPORT_SYMBOL(nvram_sync);
561
562#endif /* CONFIG_NVRAM */
563
564static struct cpu cpu_devices[NR_CPUS];
565
566int __init ppc_init(void)
567{
568 int i;
569
570 /* clear the progress line */
571 if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff);
572
573 /* register CPU devices */
574 for (i = 0; i < NR_CPUS; i++)
575 if (cpu_possible(i))
576 register_cpu(&cpu_devices[i], i, NULL);
577
578 /* call platform init */
579 if (ppc_md.init != NULL) {
580 ppc_md.init();
581 }
582 return 0;
583}
584
585arch_initcall(ppc_init);
586
587/* Warning, IO base is not yet inited */
588void __init setup_arch(char **cmdline_p)
589{
590 extern char *klimit;
591 extern void do_init_bootmem(void);
592
593 /* so udelay does something sensible, assume <= 1000 bogomips */
594 loops_per_jiffy = 500000000 / HZ;
595
596#ifdef CONFIG_BOOTX_TEXT
597 map_boot_text();
598#endif
599
600 unflatten_device_tree();
601 finish_device_tree();
602
603#ifdef CONFIG_PPC_MULTIPLATFORM
604 /* This could be called "early setup arch", it must be done
605 * now because xmon need it
606 */
607 if (_machine == _MACH_Pmac)
608 pmac_feature_init(); /* New cool way */
609#endif
610
611#ifdef CONFIG_XMON
612 xmon_map_scc();
613 if (strstr(cmd_line, "xmon"))
614 xmon(NULL);
615#endif /* CONFIG_XMON */
616 if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab);
617
618#if defined(CONFIG_KGDB)
619 if (ppc_md.kgdb_map_scc)
620 ppc_md.kgdb_map_scc();
621 set_debug_traps();
622 if (strstr(cmd_line, "gdb")) {
623 if (ppc_md.progress)
624 ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000);
625 printk("kgdb breakpoint activated\n");
626 breakpoint();
627 }
628#endif
629
630 /*
631 * Set cache line size based on type of cpu as a default.
632 * Systems with OF can look in the properties on the cpu node(s)
633 * for a possibly more accurate value.
634 */
635 if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) {
636 dcache_bsize = cur_cpu_spec->dcache_bsize;
637 icache_bsize = cur_cpu_spec->icache_bsize;
638 ucache_bsize = 0;
639 } else
640 ucache_bsize = dcache_bsize = icache_bsize
641 = cur_cpu_spec->dcache_bsize;
642
643 /* reboot on panic */
644 panic_timeout = 180;
645
646 init_mm.start_code = PAGE_OFFSET;
647 init_mm.end_code = (unsigned long) _etext;
648 init_mm.end_data = (unsigned long) _edata;
649 init_mm.brk = (unsigned long) klimit;
650
651 /* Save unparsed command line copy for /proc/cmdline */
652 strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
653 *cmdline_p = cmd_line;
654
655 parse_early_param();
656
657 /* set up the bootmem stuff with available memory */
658 do_init_bootmem();
659 if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
660
661#ifdef CONFIG_PPC_OCP
662 /* Initialize OCP device list */
663 ocp_early_init();
664 if ( ppc_md.progress ) ppc_md.progress("ocp: exit", 0x3eab);
665#endif
666
667#ifdef CONFIG_DUMMY_CONSOLE
668 conswitchp = &dummy_con;
669#endif
670
671 ppc_md.setup_arch();
672 if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
673
674 paging_init();
675
676 /* this is for modules since _machine can be a define -- Cort */
677 ppc_md.ppc_machine = _machine;
678}
diff --git a/arch/powerpc/platforms/powermac/pmac_setup.c b/arch/powerpc/platforms/powermac/pmac_setup.c
index 3667e0b2b8e3..1b12bf9956cb 100644
--- a/arch/powerpc/platforms/powermac/pmac_setup.c
+++ b/arch/powerpc/platforms/powermac/pmac_setup.c
@@ -101,6 +101,8 @@ int ppc_override_l2cr = 0;
101int ppc_override_l2cr_value; 101int ppc_override_l2cr_value;
102int has_l2cache = 0; 102int has_l2cache = 0;
103 103
104int pmac_newworld = 1;
105
104static int current_root_goodness = -1; 106static int current_root_goodness = -1;
105 107
106extern int pmac_newworld; 108extern int pmac_newworld;
@@ -355,8 +357,8 @@ static void __init ohare_init(void)
355 } 357 }
356} 358}
357 359
358extern char *bootpath; 360char *bootpath;
359extern char *bootdevice; 361char *bootdevice;
360void *boot_host; 362void *boot_host;
361int boot_target; 363int boot_target;
362int boot_part; 364int boot_part;
@@ -391,6 +393,7 @@ note_scsi_host(struct device_node *node, void *host)
391 } 393 }
392 } 394 }
393} 395}
396EXPORT_SYMBOL(note_scsi_host);
394#endif 397#endif
395 398
396#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) 399#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
@@ -565,9 +568,7 @@ pmac_halt(void)
565 pmac_power_off(); 568 pmac_power_off();
566} 569}
567 570
568void __init 571void __init pmac_init(void)
569pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
570 unsigned long r6, unsigned long r7)
571{ 572{
572 /* isa_io_base gets set in pmac_find_bridges */ 573 /* isa_io_base gets set in pmac_find_bridges */
573 isa_mem_base = PMAC_ISA_MEM_BASE; 574 isa_mem_base = PMAC_ISA_MEM_BASE;