v2.4.8 -> v2.4.8.1
[opensuse:kernel.git] / arch / ppc / kernel / prom.c
1 /*
2  * BK Id: SCCS/s.prom.c 1.35 07/25/01 14:11:37 trini
3  */
4 /*
5  * Procedures for interfacing to the Open Firmware PROM on
6  * Power Macintosh computers.
7  *
8  * In particular, we are interested in the device tree
9  * and in using some of its services (exit, write to stdout).
10  *
11  * Paul Mackerras       August 1996.
12  * Copyright (C) 1996 Paul Mackerras.
13  */
14 #include <stdarg.h>
15 #include <linux/config.h>
16 #include <linux/kernel.h>
17 #include <linux/string.h>
18 #include <linux/init.h>
19 #include <linux/version.h>
20 #include <linux/threads.h>
21 #include <linux/spinlock.h>
22
23 #include <asm/init.h>
24 #include <asm/prom.h>
25 #include <asm/page.h>
26 #include <asm/processor.h>
27 #include <asm/irq.h>
28 #include <asm/io.h>
29 #include <asm/smp.h>
30 #include <asm/bootx.h>
31 #include <asm/system.h>
32 #include <asm/mmu.h>
33 #include <asm/pgtable.h>
34 #include <asm/bitops.h>
35 #include <asm/bootinfo.h>
36 #include "open_pic.h"
37
38 #ifdef CONFIG_FB
39 #include <asm/linux_logo.h>
40 #endif
41
42 /*
43  * Properties whose value is longer than this get excluded from our
44  * copy of the device tree.  This way we don't waste space storing
45  * things like "driver,AAPL,MacOS,PowerPC" properties.  But this value
46  * does need to be big enough to ensure that we don't lose things
47  * like the interrupt-map property on a PCI-PCI bridge.
48  */
49 #define MAX_PROPERTY_LENGTH     4096
50
51 struct prom_args {
52         const char *service;
53         int nargs;
54         int nret;
55         void *args[10];
56 };
57
58 struct pci_address {
59         unsigned a_hi;
60         unsigned a_mid;
61         unsigned a_lo;
62 };
63
64 struct pci_reg_property {
65         struct pci_address addr;
66         unsigned size_hi;
67         unsigned size_lo;
68 };
69
70 struct pci_range {
71         struct pci_address addr;
72         unsigned phys;
73         unsigned size_hi;
74         unsigned size_lo;
75 };
76
77 struct isa_reg_property {
78         unsigned space;
79         unsigned address;
80         unsigned size;
81 };
82
83 struct pci_intr_map {
84         struct pci_address addr;
85         unsigned dunno;
86         phandle int_ctrler;
87         unsigned intr;
88 };
89
90 typedef unsigned long interpret_func(struct device_node *, unsigned long,
91                                      int, int);
92 static interpret_func interpret_pci_props;
93 static interpret_func interpret_dbdma_props;
94 static interpret_func interpret_isa_props;
95 static interpret_func interpret_macio_props;
96 static interpret_func interpret_root_props;
97
98 #ifndef FB_MAX                  /* avoid pulling in all of the fb stuff */
99 #define FB_MAX  8
100 #endif
101 char *prom_display_paths[FB_MAX] __initdata = { 0, };
102 unsigned int prom_num_displays __initdata = 0;
103 char *of_stdout_device __initdata = 0;
104 ihandle prom_disp_node __initdata = 0;
105
106 prom_entry prom __initdata = 0;
107 ihandle prom_chosen __initdata = 0;
108 ihandle prom_stdout __initdata = 0;
109
110 extern char *klimit;
111 char *bootpath;
112 char *bootdevice;
113
114 unsigned int rtas_data;   /* physical pointer */
115 unsigned int rtas_entry;  /* physical pointer */
116 unsigned int rtas_size;
117 unsigned int old_rtas;
118
119 /* Set for a newworld or CHRP machine */
120 int use_of_interrupt_tree;
121 struct device_node *dflt_interrupt_controller;
122 int num_interrupt_controllers;
123
124 int pmac_newworld;
125
126 static struct device_node *allnodes;
127
128 #ifdef CONFIG_BOOTX_TEXT
129
130 #define NO_SCROLL
131
132 static void clearscreen(void);
133 static void flushscreen(void);
134
135 #ifndef NO_SCROLL
136 static void scrollscreen(void);
137 #endif
138
139 static void prepare_disp_BAT(void);
140
141 static void draw_byte(unsigned char c, long locX, long locY);
142 static void draw_byte_32(unsigned char *bits, unsigned long *base, int rb);
143 static void draw_byte_16(unsigned char *bits, unsigned long *base, int rb);
144 static void draw_byte_8(unsigned char *bits, unsigned long *base, int rb);
145
146 static int g_loc_X;
147 static int g_loc_Y;
148 static int g_max_loc_X;
149 static int g_max_loc_Y;
150
151 unsigned long disp_BAT[2] __initdata = {0, 0};
152
153 #define cmapsz  (16*256)
154
155 static unsigned char vga_font[cmapsz];
156
157 int bootx_text_mapped = 1;
158
159 #endif /* CONFIG_BOOTX_TEXT */
160
161
162 static void *call_prom(const char *service, int nargs, int nret, ...);
163 static void prom_exit(void);
164 static unsigned long copy_device_tree(unsigned long, unsigned long);
165 static unsigned long inspect_node(phandle, struct device_node *, unsigned long,
166                                   unsigned long, struct device_node ***);
167 static unsigned long finish_node(struct device_node *, unsigned long,
168                                  interpret_func *, int, int);
169 static unsigned long finish_node_interrupts(struct device_node *, unsigned long);
170 static unsigned long check_display(unsigned long);
171 static int prom_next_node(phandle *);
172 static void *early_get_property(unsigned long, unsigned long, char *);
173 static struct device_node *find_phandle(phandle);
174
175 #ifdef CONFIG_BOOTX_TEXT
176 static void setup_disp_fake_bi(ihandle dp);
177 static void prom_welcome(boot_infos_t* bi, unsigned long phys);
178 #endif
179
180 extern void enter_rtas(void *);
181 void phys_call_rtas(int, int, int, ...);
182
183 extern char cmd_line[512];      /* XXX */
184 boot_infos_t *boot_infos;
185 #ifdef CONFIG_BOOTX_TEXT
186 boot_infos_t *disp_bi;
187 boot_infos_t fake_bi;
188 #endif
189 unsigned long dev_tree_size;
190
191 #define ALIGN(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long))
192
193 /* Is boot-info compatible ? */
194 #define BOOT_INFO_IS_COMPATIBLE(bi)             ((bi)->compatible_version <= BOOT_INFO_VERSION)
195 #define BOOT_INFO_IS_V2_COMPATIBLE(bi)  ((bi)->version >= 2)
196 #define BOOT_INFO_IS_V4_COMPATIBLE(bi)  ((bi)->version >= 4)
197
198 /*
199  * Note that prom_init() and anything called from prom_init() must
200  * use the RELOC/PTRRELOC macros to access any static data in
201  * memory, since the kernel may be running at an address that is
202  * different from the address that it was linked at.
203  * (Note that strings count as static variables.)
204  */
205
206 static void __init
207 prom_exit()
208 {
209         struct prom_args args;
210         unsigned long offset = reloc_offset();
211
212         args.service = "exit";
213         args.nargs = 0;
214         args.nret = 0;
215         RELOC(prom)(&args);
216         for (;;)                        /* should never get here */
217                 ;
218 }
219
220 void __init
221 prom_enter(void)
222 {
223         struct prom_args args;
224         unsigned long offset = reloc_offset();
225
226         args.service = RELOC("enter");
227         args.nargs = 0;
228         args.nret = 0;
229         RELOC(prom)(&args);
230 }
231
232 static void * __init
233 call_prom(const char *service, int nargs, int nret, ...)
234 {
235         va_list list;
236         int i;
237         unsigned long offset = reloc_offset();
238         struct prom_args prom_args;
239
240         prom_args.service = service;
241         prom_args.nargs = nargs;
242         prom_args.nret = nret;
243         va_start(list, nret);
244         for (i = 0; i < nargs; ++i)
245                 prom_args.args[i] = va_arg(list, void *);
246         va_end(list);
247         for (i = 0; i < nret; ++i)
248                 prom_args.args[i + nargs] = 0;
249         RELOC(prom)(&prom_args);
250         return prom_args.args[nargs];
251 }
252
253 void __init
254 prom_print(const char *msg)
255 {
256         const char *p, *q;
257         unsigned long offset = reloc_offset();
258
259         if (RELOC(prom_stdout) == 0)
260         {
261 #ifdef CONFIG_BOOTX_TEXT
262                 if (RELOC(disp_bi) != 0)
263                         prom_drawstring(msg);
264 #endif
265                 return;
266         }
267
268         for (p = msg; *p != 0; p = q) {
269                 for (q = p; *q != 0 && *q != '\n'; ++q)
270                         ;
271                 if (q > p)
272                         call_prom(RELOC("write"), 3, 1, RELOC(prom_stdout),
273                                   p, q - p);
274                 if (*q != 0) {
275                         ++q;
276                         call_prom(RELOC("write"), 3, 1, RELOC(prom_stdout),
277                                   RELOC("\r\n"), 2);
278                 }
279         }
280 }
281
282 static void __init
283 prom_print_hex(unsigned int v)
284 {
285         char buf[16];
286         int i, c;
287
288         for (i = 0; i < 8; ++i) {
289                 c = (v >> ((7-i)*4)) & 0xf;
290                 c += (c >= 10)? ('a' - 10): '0';
291                 buf[i] = c;
292         }
293         buf[i] = ' ';
294         buf[i+1] = 0;
295         prom_print(buf);
296 }
297
298 unsigned long smp_chrp_cpu_nr __initdata = 0;
299
300 #ifdef CONFIG_SMP
301 /*
302  * With CHRP SMP we need to use the OF to start the other
303  * processors so we can't wait until smp_boot_cpus (the OF is
304  * trashed by then) so we have to put the processors into
305  * a holding pattern controlled by the kernel (not OF) before
306  * we destroy the OF.
307  *
308  * This uses a chunk of high memory, puts some holding pattern
309  * code there and sends the other processors off to there until
310  * smp_boot_cpus tells them to do something.  We do that by using
311  * physical address 0x0.  The holding pattern checks that address
312  * until its cpu # is there, when it is that cpu jumps to
313  * __secondary_start().  smp_boot_cpus() takes care of setting those
314  * values.
315  *
316  * We also use physical address 0x4 here to tell when a cpu
317  * is in its holding pattern code.
318  *
319  * -- Cort
320  */
321 static void __init
322 prom_hold_cpus(unsigned long mem)
323 {
324         extern void __secondary_hold(void);
325         unsigned long i;
326         int cpu;
327         phandle node;
328         unsigned long offset = reloc_offset();
329         char type[16], *path;
330         unsigned int reg;
331
332         /*
333          * XXX: hack to make sure we're chrp, assume that if we're
334          *      chrp we have a device_type property -- Cort
335          */
336         node = call_prom(RELOC("finddevice"), 1, 1, RELOC("/"));
337         if ( (int)call_prom(RELOC("getprop"), 4, 1, node,
338                             RELOC("device_type"),type, sizeof(type)) <= 0)
339                 return;
340
341         /* copy the holding pattern code to someplace safe (0) */
342         /* the holding pattern is now within the first 0x100
343            bytes of the kernel image -- paulus */
344         memcpy((void *)0, (void *)(KERNELBASE + offset), 0x100);
345         flush_icache_range(0, 0x100);
346
347         /* look for cpus */
348         *(unsigned long *)(0x0) = 0;
349         asm volatile("dcbf 0,%0": : "r" (0) : "memory");
350         for (node = 0; prom_next_node(&node); ) {
351                 type[0] = 0;
352                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
353                           type, sizeof(type));
354                 if (strcmp(type, RELOC("cpu")) != 0)
355                         continue;
356                 path = (char *) mem;
357                 memset(path, 0, 256);
358                 if ((int) call_prom(RELOC("package-to-path"), 3, 1,
359                                     node, path, 255) < 0)
360                         continue;
361                 reg = -1;
362                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
363                           &reg, sizeof(reg));
364                 cpu = RELOC(smp_chrp_cpu_nr)++;
365                 RELOC(smp_hw_index)[cpu] = reg;
366                 /* XXX: hack - don't start cpu 0, this cpu -- Cort */
367                 if (cpu == 0)
368                         continue;
369                 prom_print(RELOC("starting cpu "));
370                 prom_print(path);
371                 *(ulong *)(0x4) = 0;
372                 call_prom(RELOC("start-cpu"), 3, 0, node,
373                           __pa(__secondary_hold), cpu);
374                 prom_print(RELOC("..."));
375                 for ( i = 0 ; (i < 10000) && (*(ulong *)(0x4) == 0); i++ )
376                         ;
377                 if (*(ulong *)(0x4) == cpu)
378                         prom_print(RELOC("ok\n"));
379                 else {
380                         prom_print(RELOC("failed: "));
381                         prom_print_hex(*(ulong *)0x4);
382                         prom_print(RELOC("\n"));
383                 }
384         }
385 }
386 #endif /* CONFIG_SMP */
387
388 void __init
389 bootx_init(unsigned long r4, unsigned long phys)
390 {
391         boot_infos_t *bi = (boot_infos_t *) r4;
392         unsigned long space;
393         unsigned long ptr, x;
394         char *model;
395         unsigned long offset = reloc_offset();
396
397         RELOC(boot_infos) = PTRUNRELOC(bi);
398         if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
399                 bi->logicalDisplayBase = 0;
400
401 #ifdef CONFIG_BOOTX_TEXT
402         RELOC(g_loc_X) = 0;
403         RELOC(g_loc_Y) = 0;
404         RELOC(g_max_loc_X) = (bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) / 8;
405         RELOC(g_max_loc_Y) = (bi->dispDeviceRect[3] - bi->dispDeviceRect[1]) / 16;
406         RELOC(disp_bi) = PTRUNRELOC(bi);
407                 
408         clearscreen();
409
410         /* Test if boot-info is compatible. Done only in config CONFIG_BOOTX_TEXT since
411            there is nothing much we can do with an incompatible version, except display
412            a message and eventually hang the processor...
413                    
414            I'll try to keep enough of boot-info compatible in the future to always allow
415            display of this message;
416         */
417         if (!BOOT_INFO_IS_COMPATIBLE(bi))
418                 prom_print(RELOC(" !!! WARNING - Incompatible version of BootX !!!\n\n\n"));
419                 
420         prom_welcome(bi, phys);
421         flushscreen();
422 #endif  /* CONFIG_BOOTX_TEXT */ 
423                 
424         /* New BootX enters kernel with MMU off, i/os are not allowed
425            here. This hack will have been done by the boostrap anyway.
426         */
427         if (bi->version < 4) {
428                 /*
429                  * XXX If this is an iMac, turn off the USB controller.
430                  */
431                 model = (char *) early_get_property
432                         (r4 + bi->deviceTreeOffset, 4, RELOC("model"));
433                 if (model
434                     && (strcmp(model, RELOC("iMac,1")) == 0
435                         || strcmp(model, RELOC("PowerMac1,1")) == 0)) {
436                         out_le32((unsigned *)0x80880008, 1);    /* XXX */
437                 }
438         }
439                 
440         /* Move klimit to enclose device tree, args, ramdisk, etc... */
441         if (bi->version < 5) {
442                 space = bi->deviceTreeOffset + bi->deviceTreeSize;
443                 if (bi->ramDisk)
444                         space = bi->ramDisk + bi->ramDiskSize;
445         } else
446                 space = bi->totalParamsSize;
447         RELOC(klimit) = PTRUNRELOC((char *) bi + space);
448
449         /* New BootX will have flushed all TLBs and enters kernel with
450            MMU switched OFF, so this should not be useful anymore.
451         */
452         if (bi->version < 4) {
453                 /*
454                  * Touch each page to make sure the PTEs for them
455                  * are in the hash table - the aim is to try to avoid
456                  * getting DSI exceptions while copying the kernel image.
457                  */
458                 for (ptr = (KERNELBASE + offset) & PAGE_MASK;
459                      ptr < (unsigned long)bi + space; ptr += PAGE_SIZE)
460                         x = *(volatile unsigned long *)ptr;
461         }
462                 
463 #ifdef CONFIG_BOOTX_TEXT
464         prepare_disp_BAT();
465         prom_drawstring(RELOC("booting...\n"));
466         flushscreen();
467         RELOC(bootx_text_mapped) = 1;
468 #endif
469 }
470
471 #ifdef CONFIG_PPC64BRIDGE
472 /*
473  * Set up a hash table with a set of entries in it to map the
474  * first 64MB of RAM.  This is used on 64-bit machines since
475  * some of them don't have BATs.
476  * We assume the PTE will fit in the primary PTEG.
477  */
478
479 static inline void make_pte(unsigned long htab, unsigned int hsize,
480                             unsigned int va, unsigned int pa, int mode)
481 {
482         unsigned int *pteg;
483         unsigned int hash, i, vsid;
484
485         vsid = ((va >> 28) * 0x111) << 12;
486         hash = ((va ^ vsid) >> 5) & 0x7fff80;
487         pteg = (unsigned int *)(htab + (hash & (hsize - 1)));
488         for (i = 0; i < 8; ++i, pteg += 4) {
489                 if ((pteg[1] & 1) == 0) {
490                         pteg[1] = vsid | ((va >> 16) & 0xf80) | 1;
491                         pteg[3] = pa | mode;
492                         break;
493                 }
494         }
495 }
496
497 extern unsigned long _SDR1;
498 extern PTE *Hash;
499 extern unsigned long Hash_size;
500
501 static void __init
502 prom_alloc_htab(void)
503 {
504         unsigned int hsize;
505         unsigned long htab;
506         unsigned int addr;
507         unsigned long offset = reloc_offset();
508
509         /*
510          * Because of OF bugs we can't use the "claim" client
511          * interface to allocate memory for the hash table.
512          * This code is only used on 64-bit PPCs, and the only
513          * 64-bit PPCs at the moment are RS/6000s, and their
514          * OF is based at 0xc00000 (the 12M point), so we just
515          * arbitrarily use the 0x800000 - 0xc00000 region for the
516          * hash table.
517          *  -- paulus.
518          */
519 #ifdef CONFIG_POWER4
520         hsize = 4 << 20;        /* POWER4 has no BATs */
521 #else
522         hsize = 2 << 20;
523 #endif /* CONFIG_POWER4 */
524         htab = (8 << 20);
525         RELOC(Hash) = (void *)(htab + KERNELBASE);
526         RELOC(Hash_size) = hsize;
527         RELOC(_SDR1) = htab + __ilog2(hsize) - 18;
528
529         /*
530          * Put in PTEs for the first 64MB of RAM
531          */
532         cacheable_memzero((void *)htab, hsize);
533         for (addr = 0; addr < 0x4000000; addr += 0x1000)
534                 make_pte(htab, hsize, addr + KERNELBASE, addr,
535                          _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX);
536 }
537 #endif /* CONFIG_PPC64BRIDGE */
538
539 static void __init
540 prom_instantiate_rtas(void)
541 {
542         ihandle prom_rtas;
543         unsigned int i;
544         struct prom_args prom_args;
545         unsigned long offset = reloc_offset();
546
547         prom_rtas = call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas"));
548         if (prom_rtas == (void *) -1)
549                 return;
550
551         RELOC(rtas_size) = 0;
552         call_prom(RELOC("getprop"), 4, 1, prom_rtas,
553                   RELOC("rtas-size"), &RELOC(rtas_size), sizeof(rtas_size));
554         prom_print(RELOC("instantiating rtas"));
555         if (RELOC(rtas_size) == 0) {
556                 RELOC(rtas_data) = 0;
557         } else {
558                 /*
559                  * Ask OF for some space for RTAS.
560                  * Actually OF has bugs so we just arbitrarily
561                  * use memory at the 6MB point.
562                  */
563                 RELOC(rtas_data) = 6 << 20;
564                 prom_print(RELOC(" at "));
565                 prom_print_hex(RELOC(rtas_data));
566         }
567
568         prom_rtas = call_prom(RELOC("open"), 1, 1, RELOC("/rtas"));
569         prom_print(RELOC("..."));
570         prom_args.service = RELOC("call-method");
571         prom_args.nargs = 3;
572         prom_args.nret = 2;
573         prom_args.args[0] = RELOC("instantiate-rtas");
574         prom_args.args[1] = prom_rtas;
575         prom_args.args[2] = (void *) RELOC(rtas_data);
576         RELOC(prom)(&prom_args);
577         i = 0;
578         if (prom_args.args[3] == 0)
579                 i = (unsigned int)prom_args.args[4];
580         RELOC(rtas_entry) = i;
581         if ((RELOC(rtas_entry) == -1) || (RELOC(rtas_entry) == 0))
582                 prom_print(RELOC(" failed\n"));
583         else
584                 prom_print(RELOC(" done\n"));
585 }
586
587 /*
588  * We enter here early on, when the Open Firmware prom is still
589  * handling exceptions and the MMU hash table for us.
590  */
591 unsigned long __init
592 prom_init(int r3, int r4, prom_entry pp)
593 {
594         int chrp = 0;
595         unsigned long mem;
596         ihandle prom_mmu, prom_op;
597         unsigned long offset = reloc_offset();
598         int l;
599         char *p, *d;
600         int prom_version = 0;
601         unsigned long phys;
602
603         /* Default */
604         phys = offset + KERNELBASE;
605
606         /* First get a handle for the stdout device */
607         RELOC(prom) = pp;
608         RELOC(prom_chosen) = call_prom(RELOC("finddevice"), 1, 1,
609                                        RELOC("/chosen"));
610         if (RELOC(prom_chosen) == (void *)-1)
611                 prom_exit();
612         if ((int) call_prom(RELOC("getprop"), 4, 1, RELOC(prom_chosen),
613                             RELOC("stdout"), &RELOC(prom_stdout),
614                             sizeof(prom_stdout)) <= 0)
615                 prom_exit();
616
617         /* Get the full OF pathname of the stdout device */
618         mem = (unsigned long) RELOC(klimit) + offset;
619         p = (char *) mem;
620         memset(p, 0, 256);
621         call_prom(RELOC("instance-to-path"), 3, 1, RELOC(prom_stdout), p, 255);
622         RELOC(of_stdout_device) = PTRUNRELOC(p);
623         mem += strlen(p) + 1;
624
625         /* Find the OF version */
626         prom_op = call_prom(RELOC("finddevice"), 1, 1, RELOC("/openprom"));
627         prom_version = 0;
628         if (prom_op != (void*)-1) {
629                 char model[64];
630                 int sz;
631                 sz = (int)call_prom(RELOC("getprop"), 4, 1, prom_op,
632                                     RELOC("model"), model, 64);
633                 if (sz > 0) {
634                         char *c;
635                         /* hack to skip the ibm chrp firmware # */
636                         if ( strncmp(model,RELOC("IBM"),3) ) {
637                                 for (c = model; *c; c++)
638                                         if (*c >= '0' && *c <= '9') {
639                                                 prom_version = *c - '0';
640                                                 break;
641                                         }
642                         }
643                         else
644                                 chrp = 1;
645                 }
646         }
647         if (prom_version >= 3)
648                 prom_print(RELOC("OF Version 3 detected.\n"));
649
650         /* Get the boot device and translate it to a full OF pathname. */
651         p = (char *) mem;
652         l = (int) call_prom(RELOC("getprop"), 4, 1, RELOC(prom_chosen),
653                             RELOC("bootpath"), p, 1<<20);
654         if (l > 0) {
655                 p[l] = 0;       /* should already be null-terminated */
656                 RELOC(bootpath) = PTRUNRELOC(p);
657                 mem += l + 1;
658                 d = (char *) mem;
659                 *d = 0;
660                 call_prom(RELOC("canon"), 3, 1, p, d, 1<<20);
661                 RELOC(bootdevice) = PTRUNRELOC(d);
662                 mem = ALIGN(mem + strlen(d) + 1);
663         }
664
665         prom_instantiate_rtas();
666
667 #ifdef CONFIG_PPC64BRIDGE
668         /*
669          * Find out how much memory we have and allocate a
670          * suitably-sized hash table.
671          */
672         prom_alloc_htab();
673 #endif
674
675         mem = check_display(mem);
676
677         prom_print(RELOC("copying OF device tree..."));
678         mem = copy_device_tree(mem, mem + (1<<20));
679         prom_print(RELOC("done\n"));
680
681 #ifdef CONFIG_SMP
682         prom_hold_cpus(mem);
683 #endif
684
685         RELOC(klimit) = (char *) (mem - offset);
686
687         /* If we are already running at 0xc0000000, we assume we were loaded by
688          * an OF bootloader which did set a BAT for us. This breaks OF translate
689          * so we force phys to be 0
690          */
691         if (offset == 0)
692                 phys = 0;
693         else {
694             if ((int) call_prom(RELOC("getprop"), 4, 1, RELOC(prom_chosen),
695                             RELOC("mmu"), &prom_mmu, sizeof(prom_mmu)) <= 0) {  
696                 prom_print(RELOC(" no MMU found\n"));
697             } else {
698                 int nargs;
699                 struct prom_args prom_args;
700                 nargs = 4;
701                 prom_args.service = RELOC("call-method");
702                 prom_args.nargs = nargs;
703                 prom_args.nret = 4;
704                 prom_args.args[0] = RELOC("translate");
705                 prom_args.args[1] = prom_mmu;
706                 prom_args.args[2] = (void *)(offset + KERNELBASE);
707                 prom_args.args[3] = (void *)1;
708                 RELOC(prom)(&prom_args);
709
710                 /* We assume the phys. address size is 3 cells */
711                 if (prom_args.args[nargs] != 0)
712                         prom_print(RELOC(" (translate failed)\n"));
713                 else
714                         phys = (unsigned long)prom_args.args[nargs+3];
715             }
716         }
717
718 #ifdef CONFIG_BOOTX_TEXT
719         if (RELOC(prom_disp_node) != 0)
720                 setup_disp_fake_bi(RELOC(prom_disp_node));
721 #endif
722
723         /* Use quiesce call to get OF to shut down any devices it's using */
724         prom_print(RELOC("Calling quiesce ...\n"));
725         call_prom(RELOC("quiesce"), 0, 0);
726
727 #ifdef CONFIG_BOOTX_TEXT
728         if (!chrp && RELOC(disp_bi)) {
729                 RELOC(prom_stdout) = 0; /* stop OF output */
730                 clearscreen();
731                 prepare_disp_BAT();
732                 prom_welcome(PTRRELOC(RELOC(disp_bi)), phys);
733                 prom_drawstring(RELOC("booting...\n"));
734                 RELOC(bootx_text_mapped) = 1;
735         } else {
736                 RELOC(bootx_text_mapped) = 0;
737         }
738 #endif
739
740         prom_print(RELOC("returning "));
741         prom_print_hex(phys);
742         prom_print(RELOC(" from prom_init\n"));
743         RELOC(prom_stdout) = 0;
744         return phys;
745 }
746
747 void phys_call_rtas(int service, int nargs, int nret, ...)
748 {
749         va_list list;
750         union {
751                 unsigned long words[16];
752                 double align;
753         } u;
754         unsigned long offset = reloc_offset();
755         void (*rtas)(void *, unsigned long);
756         int i;
757
758         u.words[0] = service;
759         u.words[1] = nargs;
760         u.words[2] = nret;
761         va_start(list, nret);
762         for (i = 0; i < nargs; ++i)
763                 u.words[i+3] = va_arg(list, unsigned long);
764         va_end(list);
765
766         rtas = (void (*)(void *, unsigned long)) RELOC(rtas_entry);
767         rtas(&u, RELOC(rtas_data));
768 }
769
770 #ifdef CONFIG_BOOTX_TEXT
771 static void __init
772 prom_welcome(boot_infos_t* bi, unsigned long phys)
773 {
774         unsigned long offset = reloc_offset();
775         unsigned long flags;
776         unsigned long pvr;
777         
778         prom_drawstring(RELOC("Welcome to Linux, kernel " UTS_RELEASE "\n"));
779         prom_drawstring(RELOC("\nstarted at       : 0x"));
780         prom_drawhex(phys);
781         prom_drawstring(RELOC("\nlinked at        : 0x"));
782         prom_drawhex(KERNELBASE);
783         prom_drawstring(RELOC("\nframe buffer at  : 0x"));
784         prom_drawhex((unsigned long)bi->dispDeviceBase);
785         prom_drawstring(RELOC(" (phys), 0x"));
786         prom_drawhex((unsigned long)bi->logicalDisplayBase);
787         prom_drawstring(RELOC(" (log)"));
788         prom_drawstring(RELOC("\nklimit           : 0x"));
789         prom_drawhex((unsigned long)RELOC(klimit));
790         prom_drawstring(RELOC("\nMSR              : 0x"));
791         __asm__ __volatile__ ("mfmsr %0" : "=r" (flags));
792         prom_drawhex(flags);
793         __asm__ __volatile__ ("mfspr %0, 287" : "=r" (pvr));
794         pvr >>= 16;
795         if (pvr > 1) {
796             prom_drawstring(RELOC("\nHID0             : 0x"));
797             __asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags));
798             prom_drawhex(flags);
799         }
800         if (pvr == 8 || pvr == 12 || pvr == 0x800c) {
801             prom_drawstring(RELOC("\nICTC             : 0x"));
802             __asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags));
803             prom_drawhex(flags);
804         }
805         prom_drawstring(RELOC("\n\n"));
806 }
807
808 /* Calc BAT values for mapping the display and store them
809  * in disp_BAT.  Those values are then used from head.S to map
810  * the display during identify_machine() and MMU_Init()
811  * 
812  * For now, the display is mapped in place (1:1). This should
813  * be changed if the display physical address overlaps
814  * KERNELBASE, which is fortunately not the case on any machine
815  * I know of. This mapping is temporary and will disappear as
816  * soon as the setup done by MMU_Init() is applied
817  * 
818  * For now, we align the BAT and then map 8Mb on 601 and 16Mb
819  * on other PPCs. This may cause trouble if the framebuffer
820  * is really badly aligned, but I didn't encounter this case
821  * yet.
822  */
823 static void __init
824 prepare_disp_BAT(void)
825 {
826         unsigned long offset = reloc_offset();
827         boot_infos_t* bi = PTRRELOC(RELOC(disp_bi));
828         unsigned long addr = (unsigned long)bi->dispDeviceBase;
829         
830         if ((_get_PVR() >> 16) != 1) {
831                 /* 603, 604, G3, G4, ... */
832                 addr &= 0xFF000000UL;
833                 RELOC(disp_BAT[0]) = addr | (BL_16M<<2) | 2;
834                 RELOC(disp_BAT[1]) = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);          
835         } else {
836                 /* 601 */
837                 addr &= 0xFF800000UL;
838                 RELOC(disp_BAT[0]) = addr | (_PAGE_NO_CACHE | PP_RWXX) | 4;
839                 RELOC(disp_BAT[1]) = addr | BL_8M | 0x40;
840         }
841         bi->logicalDisplayBase = bi->dispDeviceBase;
842 }
843
844 #endif
845
846 static int __init
847 prom_set_color(ihandle ih, int i, int r, int g, int b)
848 {
849         struct prom_args prom_args;
850         unsigned long offset = reloc_offset();
851
852         prom_args.service = RELOC("call-method");
853         prom_args.nargs = 6;
854         prom_args.nret = 1;
855         prom_args.args[0] = RELOC("color!");
856         prom_args.args[1] = ih;
857         prom_args.args[2] = (void *) i;
858         prom_args.args[3] = (void *) b;
859         prom_args.args[4] = (void *) g;
860         prom_args.args[5] = (void *) r;
861         RELOC(prom)(&prom_args);
862         return (int) prom_args.args[6];
863 }
864
865 /*
866  * If we have a display that we don't know how to drive,
867  * we will want to try to execute OF's open method for it
868  * later.  However, OF will probably fall over if we do that
869  * we've taken over the MMU.
870  * So we check whether we will need to open the display,
871  * and if so, open it now.
872  */
873 static unsigned long __init
874 check_display(unsigned long mem)
875 {
876         phandle node;
877         ihandle ih;
878         int i;
879         unsigned long offset = reloc_offset();
880         char type[16], *path;
881         static unsigned char default_colors[] = {
882                 0x00, 0x00, 0x00,
883                 0x00, 0x00, 0xaa,
884                 0x00, 0xaa, 0x00,
885                 0x00, 0xaa, 0xaa,
886                 0xaa, 0x00, 0x00,
887                 0xaa, 0x00, 0xaa,
888                 0xaa, 0xaa, 0x00,
889                 0xaa, 0xaa, 0xaa,
890                 0x55, 0x55, 0x55,
891                 0x55, 0x55, 0xff,
892                 0x55, 0xff, 0x55,
893                 0x55, 0xff, 0xff,
894                 0xff, 0x55, 0x55,
895                 0xff, 0x55, 0xff,
896                 0xff, 0xff, 0x55,
897                 0xff, 0xff, 0xff
898         };
899
900         RELOC(prom_disp_node) = 0;
901
902         for (node = 0; prom_next_node(&node); ) {
903                 type[0] = 0;
904                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
905                           type, sizeof(type));
906                 if (strcmp(type, RELOC("display")) != 0)
907                         continue;
908                 /* It seems OF doesn't null-terminate the path :-( */
909                 path = (char *) mem;
910                 memset(path, 0, 256);
911                 if ((int) call_prom(RELOC("package-to-path"), 3, 1,
912                                     node, path, 255) < 0)
913                         continue;
914
915                 /*
916                  * If this display is the device that OF is using for stdout,
917                  * move it to the front of the list.
918                  */
919                 mem += strlen(path) + 1;
920                 i = RELOC(prom_num_displays)++;
921                 if (RELOC(of_stdout_device) != 0 && i > 0
922                     && strcmp(PTRRELOC(RELOC(of_stdout_device)), path) == 0) {
923                         for (; i > 0; --i)
924                                 RELOC(prom_display_paths[i])
925                                         = RELOC(prom_display_paths[i-1]);
926                 }
927                 RELOC(prom_display_paths[i]) = PTRUNRELOC(path);
928                 if (i == 0)
929                         RELOC(prom_disp_node) = node;
930                 if (RELOC(prom_num_displays) >= FB_MAX)
931                         break;
932         }
933
934         /*
935          * Open the first display and set its colormap.
936          */
937         if (RELOC(prom_num_displays) > 0) {
938                 path = PTRRELOC(RELOC(prom_display_paths[0]));
939                 prom_print(RELOC("opening display "));
940                 prom_print(path);
941                 ih = call_prom(RELOC("open"), 1, 1, path);
942                 if (ih == 0 || ih == (ihandle) -1) {
943                         prom_print(RELOC("... failed\n"));
944                 } else {
945                         prom_print(RELOC("... ok\n"));
946                         /*
947                          * Setup a usable color table when the appropriate
948                          * method is available.
949                          * Should update this to use set-colors.
950                          */
951                         for (i = 0; i < 32; i++)
952                                 if (prom_set_color(ih, i, RELOC(default_colors)[i*3],
953                                                    RELOC(default_colors)[i*3+1],
954                                                    RELOC(default_colors)[i*3+2]) != 0)
955                                         break;
956
957 #ifdef CONFIG_FB
958                         for (i = 0; i < LINUX_LOGO_COLORS; i++)
959                                 if (prom_set_color(ih, i + 32,
960                                                    RELOC(linux_logo_red)[i],
961                                                    RELOC(linux_logo_green)[i],
962                                                    RELOC(linux_logo_blue)[i]) != 0)
963                                         break;
964 #endif /* CONFIG_FB */
965                 }
966         }
967
968         return ALIGN(mem);
969 }
970
971 /* This function will enable the early boot text when doing OF booting. This
972  * way, xmon output should work too
973  */
974 #ifdef CONFIG_BOOTX_TEXT
975 static void __init
976 setup_disp_fake_bi(ihandle dp)
977 {
978         int width = 640, height = 480, depth = 8, pitch;
979         unsigned address;
980         boot_infos_t* bi;
981         unsigned long offset = reloc_offset();
982         struct pci_reg_property addrs[8];
983         int i, naddrs;
984         char name[32];
985         char *getprop = RELOC("getprop");
986
987         prom_print(RELOC("Initializing fake screen: "));
988
989         memset(name, 0, sizeof(name));
990         call_prom(getprop, 4, 1, dp, RELOC("name"), name, sizeof(name));
991         name[sizeof(name)-1] = 0;
992         prom_print(name);
993         prom_print(RELOC("\n"));
994         call_prom(getprop, 4, 1, dp, RELOC("width"), &width, sizeof(width));
995         call_prom(getprop, 4, 1, dp, RELOC("height"), &height, sizeof(height));
996         call_prom(getprop, 4, 1, dp, RELOC("depth"), &depth, sizeof(depth));
997         pitch = width * ((depth + 7) / 8);
998         call_prom(getprop, 4, 1, dp, RELOC("linebytes"),
999                   &pitch, sizeof(pitch));
1000         if (pitch == 1)
1001                 pitch = 0x1000;         /* for strange IBM display */
1002         address = 0;
1003         call_prom(getprop, 4, 1, dp, RELOC("address"),
1004                   &address, sizeof(address));
1005         if (address == 0) {
1006                 /* look for an assigned address with a size of >= 1MB */
1007                 naddrs = (int) call_prom(getprop, 4, 1, dp,
1008                                 RELOC("assigned-addresses"),
1009                                 addrs, sizeof(addrs));
1010                 naddrs /= sizeof(struct pci_reg_property);
1011                 for (i = 0; i < naddrs; ++i) {
1012                         if (addrs[i].size_lo >= (1 << 20)) {
1013                                 address = addrs[i].addr.a_lo;
1014                                 /* use the BE aperture if possible */
1015                                 if (addrs[i].size_lo >= (16 << 20))
1016                                         address += (8 << 20);
1017                                 break;
1018                         }
1019                 }
1020                 if (address == 0) {
1021                         prom_print(RELOC("Failed to get address\n"));
1022                         return;
1023                 }
1024         }
1025         /* kludge for valkyrie */
1026         if (strcmp(name, RELOC("valkyrie")) == 0) 
1027                 address += 0x1000;
1028  
1029         RELOC(disp_bi) = &fake_bi;
1030         bi = PTRRELOC((&fake_bi));
1031         RELOC(g_loc_X) = 0;
1032         RELOC(g_loc_Y) = 0;
1033         RELOC(g_max_loc_X) = width / 8;
1034         RELOC(g_max_loc_Y) = height / 16;
1035         bi->logicalDisplayBase = (unsigned char *)address;
1036         bi->dispDeviceBase = (unsigned char *)address;
1037         bi->dispDeviceRowBytes = pitch;
1038         bi->dispDeviceDepth = depth;
1039         bi->dispDeviceRect[0] = bi->dispDeviceRect[1] = 0;
1040         bi->dispDeviceRect[2] = width;
1041         bi->dispDeviceRect[3] = height;
1042 }
1043 #endif
1044
1045 static int __init
1046 prom_next_node(phandle *nodep)
1047 {
1048         phandle node;
1049         unsigned long offset = reloc_offset();
1050
1051         if ((node = *nodep) != 0
1052             && (*nodep = call_prom(RELOC("child"), 1, 1, node)) != 0)
1053                 return 1;
1054         if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)
1055                 return 1;
1056         for (;;) {
1057                 if ((node = call_prom(RELOC("parent"), 1, 1, node)) == 0)
1058                         return 0;
1059                 if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)
1060                         return 1;
1061         }
1062 }
1063
1064 /*
1065  * Make a copy of the device tree from the PROM.
1066  */
1067 static unsigned long __init
1068 copy_device_tree(unsigned long mem_start, unsigned long mem_end)
1069 {
1070         phandle root;
1071         unsigned long new_start;
1072         struct device_node **allnextp;
1073         unsigned long offset = reloc_offset();
1074
1075         root = call_prom(RELOC("peer"), 1, 1, (phandle)0);
1076         if (root == (phandle)0) {
1077                 prom_print(RELOC("couldn't get device tree root\n"));
1078                 prom_exit();
1079         }
1080         allnextp = &RELOC(allnodes);
1081         mem_start = ALIGN(mem_start);
1082         new_start = inspect_node(root, 0, mem_start, mem_end, &allnextp);
1083         *allnextp = 0;
1084         return new_start;
1085 }
1086
1087 static unsigned long __init
1088 inspect_node(phandle node, struct device_node *dad,
1089              unsigned long mem_start, unsigned long mem_end,
1090              struct device_node ***allnextpp)
1091 {
1092         int l;
1093         phandle child;
1094         struct device_node *np;
1095         struct property *pp, **prev_propp;
1096         char *prev_name, *namep;
1097         unsigned char *valp;
1098         unsigned long offset = reloc_offset();
1099
1100         np = (struct device_node *) mem_start;
1101         mem_start += sizeof(struct device_node);
1102         memset(np, 0, sizeof(*np));
1103         np->node = node;
1104         **allnextpp = PTRUNRELOC(np);
1105         *allnextpp = &np->allnext;
1106         if (dad != 0) {
1107                 np->parent = PTRUNRELOC(dad);
1108                 /* we temporarily use the `next' field as `last_child'. */
1109                 if (dad->next == 0)
1110                         dad->child = PTRUNRELOC(np);
1111                 else
1112                         dad->next->sibling = PTRUNRELOC(np);
1113                 dad->next = np;
1114         }
1115
1116         /* get and store all properties */
1117         prev_propp = &np->properties;
1118         prev_name = RELOC("");
1119         for (;;) {
1120                 pp = (struct property *) mem_start;
1121                 namep = (char *) (pp + 1);
1122                 pp->name = PTRUNRELOC(namep);
1123                 if ((int) call_prom(RELOC("nextprop"), 3, 1, node, prev_name,
1124                                     namep) <= 0)
1125                         break;
1126                 mem_start = ALIGN((unsigned long)namep + strlen(namep) + 1);
1127                 prev_name = namep;
1128                 valp = (unsigned char *) mem_start;
1129                 pp->value = PTRUNRELOC(valp);
1130                 pp->length = (int)
1131                         call_prom(RELOC("getprop"), 4, 1, node, namep,
1132                                   valp, mem_end - mem_start);
1133                 if (pp->length < 0)
1134                         continue;
1135 #ifdef MAX_PROPERTY_LENGTH
1136                 if (pp->length > MAX_PROPERTY_LENGTH)
1137                         continue; /* ignore this property */
1138 #endif
1139                 mem_start = ALIGN(mem_start + pp->length);
1140                 *prev_propp = PTRUNRELOC(pp);
1141                 prev_propp = &pp->next;
1142         }
1143         if (np->node != NULL) {
1144                 /* Add a "linux,phandle" property" */
1145                 pp = (struct property *) mem_start;
1146                 *prev_propp = PTRUNRELOC(pp);
1147                 prev_propp = &pp->next;
1148                 namep = (char *) (pp + 1);
1149                 pp->name = PTRUNRELOC(namep);
1150                 /* Work around a GCC3 bug */
1151                 memcpy(namep, RELOC("linux,phandle"), sizeof("linux,phandle"));
1152                 mem_start = ALIGN((unsigned long)namep + strlen(namep) + 1);
1153                 pp->value = (unsigned char *) PTRUNRELOC(&np->node);
1154                 pp->length = sizeof(np->node);
1155         }
1156         *prev_propp = NULL;
1157
1158         /* get the node's full name */
1159         l = (int) call_prom(RELOC("package-to-path"), 3, 1, node,
1160                             (char *) mem_start, mem_end - mem_start);
1161         if (l >= 0) {
1162                 np->full_name = PTRUNRELOC((char *) mem_start);
1163                 *(char *)(mem_start + l) = 0;
1164                 mem_start = ALIGN(mem_start + l + 1);
1165         }
1166
1167         /* do all our children */
1168         child = call_prom(RELOC("child"), 1, 1, node);
1169         while (child != (void *)0) {
1170                 mem_start = inspect_node(child, np, mem_start, mem_end,
1171                                          allnextpp);
1172                 child = call_prom(RELOC("peer"), 1, 1, child);
1173         }
1174
1175         return mem_start;
1176 }
1177
1178 /*
1179  * finish_device_tree is called once things are running normally
1180  * (i.e. with text and data mapped to the address they were linked at).
1181  * It traverses the device tree and fills in the name, type,
1182  * {n_}addrs and {n_}intrs fields of each node.
1183  */
1184 void __init
1185 finish_device_tree(void)
1186 {
1187         unsigned long mem = (unsigned long) klimit;
1188         struct device_node *np;
1189
1190         /* All newworld pmac machines and CHRPs now use the interrupt tree */
1191         for (np = allnodes; np != NULL; np = np->allnext) {
1192                 if (get_property(np, "interrupt-parent", 0)) {
1193                         use_of_interrupt_tree = 1;
1194                         break;
1195                 }
1196         }
1197         if (_machine == _MACH_Pmac && use_of_interrupt_tree)
1198                 pmac_newworld = 1;
1199
1200 #ifdef CONFIG_BOOTX_TEXT
1201         if (boot_infos && pmac_newworld) {
1202                 prom_print("WARNING ! BootX/miBoot booting is not supported on this machine\n");
1203                 prom_print("          You should use an Open Firmware bootloader\n");
1204         }
1205 #endif /* CONFIG_BOOTX_TEXT */
1206
1207         if (use_of_interrupt_tree) {
1208                 /*
1209                  * We want to find out here how many interrupt-controller
1210                  * nodes there are, and if we are booted from BootX,
1211                  * we need a pointer to the first (and hopefully only)
1212                  * such node.  But we can't use find_devices here since
1213                  * np->name has not been set yet.  -- paulus
1214                  */
1215                 int n = 0;
1216                 char *name;
1217
1218                 for (np = allnodes; np != NULL; np = np->allnext) {
1219                         if ((name = get_property(np, "name", NULL)) == NULL
1220                             || strcmp(name, "interrupt-controller") != 0)
1221                                 continue;
1222                         if (n == 0)
1223                                 dflt_interrupt_controller = np;
1224                         ++n;
1225                 }
1226                 num_interrupt_controllers = n;
1227         }
1228
1229         mem = finish_node(allnodes, mem, NULL, 1, 1);
1230         dev_tree_size = mem - (unsigned long) allnodes;
1231         klimit = (char *) mem;
1232 }
1233
1234 /*
1235  * early_get_property is used to access the device tree image prepared
1236  * by BootX very early on, before the pointers in it have been relocated.
1237  */
1238 static void * __init
1239 early_get_property(unsigned long base, unsigned long node, char *prop)
1240 {
1241         struct device_node *np = (struct device_node *)(base + node);
1242         struct property *pp;
1243
1244         for (pp = np->properties; pp != 0; pp = pp->next) {
1245                 pp = (struct property *) (base + (unsigned long)pp);
1246                 if (strcmp((char *)((unsigned long)pp->name + base),
1247                            prop) == 0) {
1248                         return (void *)((unsigned long)pp->value + base);
1249                 }
1250         }
1251         return 0;
1252 }
1253
1254 static unsigned long __init
1255 finish_node(struct device_node *np, unsigned long mem_start,
1256             interpret_func *ifunc, int naddrc, int nsizec)
1257 {
1258         struct device_node *child;
1259         int *ip;
1260
1261         np->name = get_property(np, "name", 0);
1262         np->type = get_property(np, "device_type", 0);
1263
1264         /* get the device addresses and interrupts */
1265         if (ifunc != NULL) {
1266                 mem_start = ifunc(np, mem_start, naddrc, nsizec);
1267         }
1268         if (use_of_interrupt_tree)
1269                 mem_start = finish_node_interrupts(np, mem_start);
1270
1271         /* Look for #address-cells and #size-cells properties. */
1272         ip = (int *) get_property(np, "#address-cells", 0);
1273         if (ip != NULL)
1274                 naddrc = *ip;
1275         ip = (int *) get_property(np, "#size-cells", 0);
1276         if (ip != NULL)
1277                 nsizec = *ip;
1278
1279         /* the f50 sets the name to 'display' and 'compatible' to what we
1280          * expect for the name -- Cort
1281          */
1282         if (!strcmp(np->name, "display"))
1283                 np->name = get_property(np, "compatible", 0);
1284
1285         if (np->parent == NULL)
1286                 ifunc = interpret_root_props;
1287         else if (np->type == 0)
1288                 ifunc = NULL;
1289         else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
1290                 ifunc = interpret_pci_props;
1291         else if (!strcmp(np->type, "dbdma"))
1292                 ifunc = interpret_dbdma_props;
1293         else if (!strcmp(np->type, "mac-io")
1294                  || ifunc == interpret_macio_props)
1295                 ifunc = interpret_macio_props;
1296         else if (!strcmp(np->type, "isa"))
1297                 ifunc = interpret_isa_props;
1298         else if (!((ifunc == interpret_dbdma_props
1299                     || ifunc == interpret_macio_props)
1300                    && (!strcmp(np->type, "escc")
1301                        || !strcmp(np->type, "media-bay"))))
1302                 ifunc = NULL;
1303
1304         /* if we were booted from BootX, convert the full name */
1305         if (boot_infos
1306             && strncmp(np->full_name, "Devices:device-tree", 19) == 0) {
1307                 if (np->full_name[19] == 0) {
1308                         strcpy(np->full_name, "/");
1309                 } else if (np->full_name[19] == ':') {
1310                         char *p = np->full_name + 19;
1311                         np->full_name = p;
1312                         for (; *p; ++p)
1313                                 if (*p == ':')
1314                                         *p = '/';
1315                 }
1316         }
1317
1318         for (child = np->child; child != NULL; child = child->sibling)
1319                 mem_start = finish_node(child, mem_start, ifunc,
1320                                         naddrc, nsizec);
1321
1322         return mem_start;
1323 }
1324
1325 /*
1326  * Find the interrupt parent of a node.
1327  */
1328 static struct device_node * __init
1329 intr_parent(struct device_node *p)
1330 {
1331         phandle *parp;
1332
1333         parp = (phandle *) get_property(p, "interrupt-parent", NULL);
1334         if (parp == NULL)
1335                 return p->parent;
1336         p = find_phandle(*parp);
1337         if (p != NULL)
1338                 return p;
1339         /*
1340          * On a powermac booted with BootX, we don't get to know the
1341          * phandles for any nodes, so find_phandle will return NULL.
1342          * Fortunately these machines only have one interrupt controller
1343          * so there isn't in fact any ambiguity.  -- paulus
1344          */
1345         if (num_interrupt_controllers == 1)
1346                 p = dflt_interrupt_controller;
1347         return p;
1348 }
1349
1350 /*
1351  * Find out the size of each entry of the interrupts property
1352  * for a node.
1353  */
1354 static int __init
1355 prom_n_intr_cells(struct device_node *np)
1356 {
1357         struct device_node *p;
1358         unsigned int *icp;
1359
1360         for (p = np; (p = intr_parent(p)) != NULL; ) {
1361                 icp = (unsigned int *)
1362                         get_property(p, "#interrupt-cells", NULL);
1363                 if (icp != NULL)
1364                         return *icp;
1365                 if (get_property(p, "interrupt-controller", NULL) != NULL
1366                     || get_property(p, "interrupt-map", NULL) != NULL) {
1367                         printk("oops, node %s doesn't have #interrupt-cells\n",
1368                                p->full_name);
1369                         return 1;
1370                 }
1371         }
1372         printk("prom_n_intr_cells failed for %s\n", np->full_name);
1373         return 1;
1374 }
1375
1376 /*
1377  * Map an interrupt from a device up to the platform interrupt
1378  * descriptor.
1379  */
1380 static int __init
1381 map_interrupt(unsigned int **irq, struct device_node **ictrler,
1382               struct device_node *np, unsigned int *ints, int nintrc)
1383 {
1384         struct device_node *p, *ipar;
1385         unsigned int *imap, *imask, *ip;
1386         int i, imaplen, match;
1387         int newintrc, newaddrc;
1388         unsigned int *reg;
1389         int naddrc;
1390
1391         reg = (unsigned int *) get_property(np, "reg", NULL);
1392         naddrc = prom_n_addr_cells(np);
1393         p = intr_parent(np);
1394         while (p != NULL) {
1395                 if (get_property(p, "interrupt-controller", NULL) != NULL)
1396                         /* this node is an interrupt controller, stop here */
1397                         break;
1398                 imap = (unsigned int *)
1399                         get_property(p, "interrupt-map", &imaplen);
1400                 if (imap == NULL) {
1401                         p = intr_parent(p);
1402                         continue;
1403                 }
1404                 imask = (unsigned int *)
1405                         get_property(p, "interrupt-map-mask", NULL);
1406                 if (imask == NULL) {
1407                         printk("oops, %s has interrupt-map but no mask\n",
1408                                p->full_name);
1409                         return 0;
1410                 }
1411                 imaplen /= sizeof(unsigned int);
1412                 match = 0;
1413                 ipar = NULL;
1414                 while (imaplen > 0 && !match) {
1415                         /* check the child-interrupt field */
1416                         match = 1;
1417                         for (i = 0; i < naddrc && match; ++i)
1418                                 match = ((reg[i] ^ imap[i]) & imask[i]) == 0;
1419                         for (; i < naddrc + nintrc && match; ++i)
1420                                 match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0;
1421                         imap += naddrc + nintrc;
1422                         imaplen -= naddrc + nintrc;
1423                         /* grab the interrupt parent */
1424                         ipar = find_phandle((phandle) *imap++);
1425                         --imaplen;
1426                         if (ipar == NULL && num_interrupt_controllers == 1)
1427                                 /* cope with BootX not giving us phandles */
1428                                 ipar = dflt_interrupt_controller;
1429                         if (ipar == NULL) {
1430                                 printk("oops, no int parent %x in map of %s\n",
1431                                        imap[-1], p->full_name);
1432                                 return 0;
1433                         }
1434                         /* find the parent's # addr and intr cells */
1435                         ip = (unsigned int *)
1436                                 get_property(ipar, "#interrupt-cells", NULL);
1437                         if (ip == NULL) {
1438                                 printk("oops, no #interrupt-cells on %s\n",
1439                                        ipar->full_name);
1440                                 return 0;
1441                         }
1442                         newintrc = *ip;
1443                         ip = (unsigned int *)
1444                                 get_property(ipar, "#address-cells", NULL);
1445                         newaddrc = (ip == NULL)? 0: *ip;
1446                         imap += newaddrc + newintrc;
1447                         imaplen -= newaddrc + newintrc;
1448                 }
1449                 if (imaplen < 0) {
1450                         printk("oops, error decoding int-map on %s, len=%d\n",
1451                                p->full_name, imaplen);
1452                         return 0;
1453                 }
1454                 if (!match) {
1455                         printk("oops, no match in %s int-map for %s\n",
1456                                p->full_name, np->full_name);
1457                         return 0;
1458                 }
1459                 p = ipar;
1460                 naddrc = newaddrc;
1461                 nintrc = newintrc;
1462                 ints = imap - nintrc;
1463                 reg = ints - naddrc;
1464         }
1465         if (p == NULL)
1466                 printk("hmmm, int tree for %s doesn't have ctrler\n",
1467                        np->full_name);
1468         *irq = ints;
1469         *ictrler = p;
1470         return nintrc;
1471 }
1472
1473 /*
1474  * New version of finish_node_interrupts.
1475  */
1476 static unsigned long __init
1477 finish_node_interrupts(struct device_node *np, unsigned long mem_start)
1478 {
1479         unsigned int *ints;
1480         int intlen, intrcells;
1481         int i, j, n, offset;
1482         unsigned int *irq;
1483         struct device_node *ic;
1484
1485         ints = (unsigned int *) get_property(np, "interrupts", &intlen);
1486         if (ints == NULL)
1487                 return mem_start;
1488         intrcells = prom_n_intr_cells(np);
1489         intlen /= intrcells * sizeof(unsigned int);
1490         np->n_intrs = intlen;
1491         np->intrs = (struct interrupt_info *) mem_start;
1492         mem_start += intlen * sizeof(struct interrupt_info);
1493
1494         for (i = 0; i < intlen; ++i) {
1495                 np->intrs[i].line = 0;
1496                 np->intrs[i].sense = 1;
1497                 n = map_interrupt(&irq, &ic, np, ints, intrcells);
1498                 if (n <= 0)
1499                         continue;
1500                 offset = 0;
1501                 /*
1502                  * On a CHRP we have an 8259 which is subordinate to
1503                  * the openpic in the interrupt tree, but we want the
1504                  * openpic's interrupt numbers offsetted, not the 8259's.
1505                  * So we apply the offset if the controller is at the
1506                  * root of the interrupt tree, i.e. has no interrupt-parent.
1507                  * This doesn't cope with the general case of multiple
1508                  * cascaded interrupt controllers, but then neither will
1509                  * irq.c at the moment either.  -- paulus
1510                  */
1511                 if (num_interrupt_controllers > 1 && ic != NULL
1512                     && get_property(ic, "interrupt-parent", NULL) == NULL)
1513                         offset = 16;
1514                 np->intrs[i].line = irq[0] + offset;
1515                 if (n > 1)
1516                         np->intrs[i].sense = irq[1];
1517                 if (n > 2) {
1518                         printk("hmmm, got %d intr cells for %s:", n,
1519                                np->full_name);
1520                         for (j = 0; j < n; ++j)
1521                                 printk(" %d", irq[j]);
1522                         printk("\n");
1523                 }
1524                 ints += intrcells;
1525         }
1526
1527         return mem_start;
1528 }
1529
1530 /*
1531  * When BootX makes a copy of the device tree from the MacOS
1532  * Name Registry, it is in the format we use but all of the pointers
1533  * are offsets from the start of the tree.
1534  * This procedure updates the pointers.
1535  */
1536 void __init
1537 relocate_nodes(void)
1538 {
1539         unsigned long base;
1540         struct device_node *np;
1541         struct property *pp;
1542
1543 #define ADDBASE(x)      (x = (x)? ((typeof (x))((unsigned long)(x) + base)): 0)
1544
1545         base = (unsigned long) boot_infos + boot_infos->deviceTreeOffset;
1546         allnodes = (struct device_node *)(base + 4);
1547         for (np = allnodes; np != 0; np = np->allnext) {
1548                 ADDBASE(np->full_name);
1549                 ADDBASE(np->properties);
1550                 ADDBASE(np->parent);
1551                 ADDBASE(np->child);
1552                 ADDBASE(np->sibling);
1553                 ADDBASE(np->allnext);
1554                 for (pp = np->properties; pp != 0; pp = pp->next) {
1555                         ADDBASE(pp->name);
1556                         ADDBASE(pp->value);
1557                         ADDBASE(pp->next);
1558                 }
1559         }
1560 }
1561
1562 int __init
1563 prom_n_addr_cells(struct device_node* np)
1564 {
1565         int* ip;
1566         do {
1567                 if (np->parent)
1568                         np = np->parent;
1569                 ip = (int *) get_property(np, "#address-cells", 0);
1570                 if (ip != NULL)
1571                         return *ip;
1572         } while (np->parent);
1573         /* No #address-cells property for the root node, default to 1 */
1574         return 1;
1575 }
1576
1577 int __init
1578 prom_n_size_cells(struct device_node* np)
1579 {
1580         int* ip;
1581         do {
1582                 if (np->parent)
1583                         np = np->parent;
1584                 ip = (int *) get_property(np, "#size-cells", 0);
1585                 if (ip != NULL)
1586                         return *ip;
1587         } while (np->parent);
1588         /* No #size-cells property for the root node, default to 1 */
1589         return 1;
1590 }
1591
1592 static unsigned long __init
1593 interpret_pci_props(struct device_node *np, unsigned long mem_start,
1594                     int naddrc, int nsizec)
1595 {
1596         struct address_range *adr;
1597         struct pci_reg_property *pci_addrs;
1598         int i, l, *ip;
1599
1600         pci_addrs = (struct pci_reg_property *)
1601                 get_property(np, "assigned-addresses", &l);
1602         if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {
1603                 i = 0;
1604                 adr = (struct address_range *) mem_start;
1605                 while ((l -= sizeof(struct pci_reg_property)) >= 0) {
1606                         /* XXX assumes PCI addresses mapped 1-1 to physical */
1607                         adr[i].space = pci_addrs[i].addr.a_hi;
1608                         adr[i].address = pci_addrs[i].addr.a_lo;
1609                         adr[i].size = pci_addrs[i].size_lo;
1610                         ++i;
1611                 }
1612                 np->addrs = adr;
1613                 np->n_addrs = i;
1614                 mem_start += i * sizeof(struct address_range);
1615         }
1616
1617         if (use_of_interrupt_tree)
1618                 return mem_start;
1619
1620         ip = (int *) get_property(np, "AAPL,interrupts", &l);
1621         if (ip == 0 && np->parent)
1622                 ip = (int *) get_property(np->parent, "AAPL,interrupts", &l);
1623         if (ip == 0)
1624                 ip = (int *) get_property(np, "interrupts", &l);
1625         if (ip != 0) {
1626                 np->intrs = (struct interrupt_info *) mem_start;
1627                 np->n_intrs = l / sizeof(int);
1628                 mem_start += np->n_intrs * sizeof(struct interrupt_info);
1629                 for (i = 0; i < np->n_intrs; ++i) {
1630                         np->intrs[i].line = *ip++;
1631                         np->intrs[i].sense = 1;
1632                 }
1633         }
1634
1635         return mem_start;
1636 }
1637
1638 static unsigned long __init
1639 interpret_dbdma_props(struct device_node *np, unsigned long mem_start,
1640                       int naddrc, int nsizec)
1641 {
1642         struct reg_property *rp;
1643         struct address_range *adr;
1644         unsigned long base_address;
1645         int i, l, *ip;
1646         struct device_node *db;
1647
1648         base_address = 0;
1649         for (db = np->parent; db != NULL; db = db->parent) {
1650                 if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
1651                         base_address = db->addrs[0].address;
1652                         break;
1653                 }
1654         }
1655
1656         rp = (struct reg_property *) get_property(np, "reg", &l);
1657         if (rp != 0 && l >= sizeof(struct reg_property)) {
1658                 i = 0;
1659                 adr = (struct address_range *) mem_start;
1660                 while ((l -= sizeof(struct reg_property)) >= 0) {
1661                         adr[i].space = 0;
1662                         adr[i].address = rp[i].address + base_address;
1663                         adr[i].size = rp[i].size;
1664                         ++i;
1665                 }
1666                 np->addrs = adr;
1667                 np->n_addrs = i;
1668                 mem_start += i * sizeof(struct address_range);
1669         }
1670
1671         if (use_of_interrupt_tree)
1672                 return mem_start;
1673
1674         ip = (int *) get_property(np, "AAPL,interrupts", &l);
1675         if (ip == 0)
1676                 ip = (int *) get_property(np, "interrupts", &l);
1677         if (ip != 0) {
1678                 np->intrs = (struct interrupt_info *) mem_start;
1679                 np->n_intrs = l / sizeof(int);
1680                 mem_start += np->n_intrs * sizeof(struct interrupt_info);
1681                 for (i = 0; i < np->n_intrs; ++i) {
1682                         np->intrs[i].line = *ip++;
1683                         np->intrs[i].sense = 1;
1684                 }
1685         }
1686
1687         return mem_start;
1688 }
1689
1690 static unsigned long __init
1691 interpret_macio_props(struct device_node *np, unsigned long mem_start,
1692                       int naddrc, int nsizec)
1693 {
1694         struct reg_property *rp;
1695         struct address_range *adr;
1696         unsigned long base_address;
1697         int i, l, keylargo, *ip;
1698         struct device_node *db;
1699
1700         base_address = 0;
1701         for (db = np->parent; db != NULL; db = db->parent) {
1702                 if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
1703                         base_address = db->addrs[0].address;
1704                         keylargo = device_is_compatible(db, "Keylargo");
1705                         break;
1706                 }
1707         }
1708
1709         rp = (struct reg_property *) get_property(np, "reg", &l);
1710         if (rp != 0 && l >= sizeof(struct reg_property)) {
1711                 i = 0;
1712                 adr = (struct address_range *) mem_start;
1713                 while ((l -= sizeof(struct reg_property)) >= 0) {
1714                         adr[i].space = 0;
1715                         adr[i].address = rp[i].address + base_address;
1716                         adr[i].size = rp[i].size;
1717                         ++i;
1718                 }
1719                 np->addrs = adr;
1720                 np->n_addrs = i;
1721                 mem_start += i * sizeof(struct address_range);
1722         }
1723
1724         if (use_of_interrupt_tree)
1725                 return mem_start;
1726
1727         ip = (int *) get_property(np, "interrupts", &l);
1728         if (ip == 0)
1729                 ip = (int *) get_property(np, "AAPL,interrupts", &l);
1730         if (ip != 0) {
1731                 np->intrs = (struct interrupt_info *) mem_start;
1732                 np->n_intrs = l / sizeof(int);
1733                 for (i = 0; i < np->n_intrs; ++i) {
1734                         np->intrs[i].line = *ip++;
1735                         np->intrs[i].sense = 1;
1736                 }
1737                 mem_start += np->n_intrs * sizeof(struct interrupt_info);
1738         }
1739
1740         return mem_start;
1741 }
1742
1743 static unsigned long __init
1744 interpret_isa_props(struct device_node *np, unsigned long mem_start,
1745                     int naddrc, int nsizec)
1746 {
1747         struct isa_reg_property *rp;
1748         struct address_range *adr;
1749         int i, l, *ip;
1750
1751         rp = (struct isa_reg_property *) get_property(np, "reg", &l);
1752         if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
1753                 i = 0;
1754                 adr = (struct address_range *) mem_start;
1755                 while ((l -= sizeof(struct reg_property)) >= 0) {
1756                         adr[i].space = rp[i].space;
1757                         adr[i].address = rp[i].address
1758                                 + (adr[i].space? 0: _ISA_MEM_BASE);
1759                         adr[i].size = rp[i].size;
1760                         ++i;
1761                 }
1762                 np->addrs = adr;
1763                 np->n_addrs = i;
1764                 mem_start += i * sizeof(struct address_range);
1765         }
1766
1767         if (use_of_interrupt_tree)
1768                 return mem_start;
1769  
1770         ip = (int *) get_property(np, "interrupts", &l);
1771         if (ip != 0) {
1772                 np->intrs = (struct interrupt_info *) mem_start;
1773                 np->n_intrs = l / (2 * sizeof(int));
1774                 mem_start += np->n_intrs * sizeof(struct interrupt_info);
1775                 for (i = 0; i < np->n_intrs; ++i) {
1776                         np->intrs[i].line = *ip++;
1777                         np->intrs[i].sense = *ip++;
1778                 }
1779         }
1780
1781         return mem_start;
1782 }
1783
1784 static unsigned long __init
1785 interpret_root_props(struct device_node *np, unsigned long mem_start,
1786                      int naddrc, int nsizec)
1787 {
1788         struct address_range *adr;
1789         int i, l, *ip;
1790         unsigned int *rp;
1791         int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
1792
1793         rp = (unsigned int *) get_property(np, "reg", &l);
1794         if (rp != 0 && l >= rpsize) {
1795                 i = 0;
1796                 adr = (struct address_range *) mem_start;
1797                 while ((l -= rpsize) >= 0) {
1798                         adr[i].space = (naddrc >= 2? rp[naddrc-2]: 0);
1799                         adr[i].address = rp[naddrc - 1];
1800                         adr[i].size = rp[naddrc + nsizec - 1];
1801                         ++i;
1802                         rp += naddrc + nsizec;
1803                 }
1804                 np->addrs = adr;
1805                 np->n_addrs = i;
1806                 mem_start += i * sizeof(struct address_range);
1807         }
1808
1809         if (use_of_interrupt_tree)
1810                 return mem_start;
1811
1812         ip = (int *) get_property(np, "AAPL,interrupts", &l);
1813         if (ip == 0)
1814                 ip = (int *) get_property(np, "interrupts", &l);
1815         if (ip != 0) {
1816                 np->intrs = (struct interrupt_info *) mem_start;
1817                 np->n_intrs = l / sizeof(int);
1818                 mem_start += np->n_intrs * sizeof(struct interrupt_info);
1819                 for (i = 0; i < np->n_intrs; ++i) {
1820                         np->intrs[i].line = *ip++;
1821                         np->intrs[i].sense = 1;
1822                 }
1823         }
1824
1825         return mem_start;
1826 }
1827
1828 /*
1829  * Work out the sense (active-low level / active-high edge)
1830  * of each interrupt from the device tree.
1831  */
1832 void __init
1833 prom_get_irq_senses(unsigned char *senses, int off, int max)
1834 {
1835         struct device_node *np;
1836         int i, j;
1837
1838         /* default to level-triggered */
1839         memset(senses, 1, max - off);
1840         if (!use_of_interrupt_tree)
1841                 return;
1842
1843         for (np = allnodes; np != 0; np = np->allnext) {
1844                 for (j = 0; j < np->n_intrs; j++) {
1845                         i = np->intrs[j].line;
1846                         if (i >= off && i < max)
1847                                 senses[i-off] = np->intrs[j].sense;
1848                 }
1849         }
1850 }
1851
1852 /*
1853  * Construct and return a list of the device_nodes with a given name.
1854  */
1855 struct device_node *
1856 find_devices(const char *name)
1857 {
1858         struct device_node *head, **prevp, *np;
1859
1860         prevp = &head;
1861         for (np = allnodes; np != 0; np = np->allnext) {
1862                 if (np->name != 0 && strcasecmp(np->name, name) == 0) {
1863                         *prevp = np;
1864                         prevp = &np->next;
1865                 }
1866         }
1867         *prevp = 0;
1868         return head;
1869 }
1870
1871 /*
1872  * Construct and return a list of the device_nodes with a given type.
1873  */
1874 struct device_node *
1875 find_type_devices(const char *type)
1876 {
1877         struct device_node *head, **prevp, *np;
1878
1879         prevp = &head;
1880         for (np = allnodes; np != 0; np = np->allnext) {
1881                 if (np->type != 0 && strcasecmp(np->type, type) == 0) {
1882                         *prevp = np;
1883                         prevp = &np->next;
1884                 }
1885         }
1886         *prevp = 0;
1887         return head;
1888 }
1889
1890 /*
1891  * Returns all nodes linked together
1892  */
1893 struct device_node __openfirmware *
1894 find_all_nodes(void)
1895 {
1896         struct device_node *head, **prevp, *np;
1897
1898         prevp = &head;
1899         for (np = allnodes; np != 0; np = np->allnext) {
1900                 *prevp = np;
1901                 prevp = &np->next;
1902         }
1903         *prevp = 0;
1904         return head;
1905 }
1906
1907 /* Checks if the given "compat" string matches one of the strings in
1908  * the device's "compatible" property
1909  */
1910 int
1911 device_is_compatible(struct device_node *device, const char *compat)
1912 {
1913         const char* cp;
1914         int cplen, l;
1915
1916         cp = (char *) get_property(device, "compatible", &cplen);
1917         if (cp == NULL)
1918                 return 0;
1919         while (cplen > 0) {
1920                 if (strncasecmp(cp, compat, strlen(compat)) == 0)
1921                         return 1;
1922                 l = strlen(cp) + 1;
1923                 cp += l;
1924                 cplen -= l;
1925         }
1926
1927         return 0;
1928 }
1929
1930
1931 /*
1932  * Indicates whether the root node has a given value in its
1933  * compatible property.
1934  */
1935 int
1936 machine_is_compatible(const char *compat)
1937 {
1938         struct device_node *root;
1939         
1940         root = find_path_device("/");
1941         if (root == 0)
1942                 return 0;
1943         return device_is_compatible(root, compat);
1944 }
1945
1946 /*
1947  * Construct and return a list of the device_nodes with a given type
1948  * and compatible property.
1949  */
1950 struct device_node *
1951 find_compatible_devices(const char *type, const char *compat)
1952 {
1953         struct device_node *head, **prevp, *np;
1954
1955         prevp = &head;
1956         for (np = allnodes; np != 0; np = np->allnext) {
1957                 if (type != NULL
1958                     && !(np->type != 0 && strcasecmp(np->type, type) == 0))
1959                         continue;
1960                 if (device_is_compatible(np, compat)) {
1961                         *prevp = np;
1962                         prevp = &np->next;
1963                 }
1964         }
1965         *prevp = 0;
1966         return head;
1967 }
1968
1969 /*
1970  * Find the device_node with a given full_name.
1971  */
1972 struct device_node *
1973 find_path_device(const char *path)
1974 {
1975         struct device_node *np;
1976
1977         for (np = allnodes; np != 0; np = np->allnext)
1978                 if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
1979                         return np;
1980         return NULL;
1981 }
1982
1983 /*
1984  * Find the device_node with a given phandle.
1985  */
1986 static struct device_node __init *
1987 find_phandle(phandle ph)
1988 {
1989         struct device_node *np;
1990
1991         for (np = allnodes; np != 0; np = np->allnext)
1992                 if (np->node == ph)
1993                         return np;
1994         return NULL;
1995 }
1996
1997 /*
1998  * Find a property with a given name for a given node
1999  * and return the value.
2000  */
2001 unsigned char *
2002 get_property(struct device_node *np, const char *name, int *lenp)
2003 {
2004         struct property *pp;
2005
2006         for (pp = np->properties; pp != 0; pp = pp->next)
2007                 if (pp->name != NULL && strcmp(pp->name, name) == 0) {
2008                         if (lenp != 0)
2009                                 *lenp = pp->length;
2010                         return pp->value;
2011                 }
2012         return 0;
2013 }
2014
2015 /*
2016  * Add a property to a node
2017  */
2018 void __openfirmware
2019 prom_add_property(struct device_node* np, struct property* prop)
2020 {
2021         struct property **next = &np->properties;
2022
2023         prop->next = NULL;      
2024         while (*next)
2025                 next = &(*next)->next;
2026         *next = prop;
2027 }
2028
2029 #if 0
2030 void __openfirmware
2031 print_properties(struct device_node *np)
2032 {
2033         struct property *pp;
2034         char *cp;
2035         int i, n;
2036
2037         for (pp = np->properties; pp != 0; pp = pp->next) {
2038                 printk(KERN_INFO "%s", pp->name);
2039                 for (i = strlen(pp->name); i < 16; ++i)
2040                         printk(" ");
2041                 cp = (char *) pp->value;
2042                 for (i = pp->length; i > 0; --i, ++cp)
2043                         if ((i > 1 && (*cp < 0x20 || *cp > 0x7e))
2044                             || (i == 1 && *cp != 0))
2045                                 break;
2046                 if (i == 0 && pp->length > 1) {
2047                         /* looks like a string */
2048                         printk(" %s\n", (char *) pp->value);
2049                 } else {
2050                         /* dump it in hex */
2051                         n = pp->length;
2052                         if (n > 64)
2053                                 n = 64;
2054                         if (pp->length % 4 == 0) {
2055                                 unsigned int *p = (unsigned int *) pp->value;
2056
2057                                 n /= 4;
2058                                 for (i = 0; i < n; ++i) {
2059                                         if (i != 0 && (i % 4) == 0)
2060                                                 printk("\n                ");
2061                                         printk(" %08x", *p++);
2062                                 }
2063                         } else {
2064                                 unsigned char *bp = pp->value;
2065
2066                                 for (i = 0; i < n; ++i) {
2067                                         if (i != 0 && (i % 16) == 0)
2068                                                 printk("\n                ");
2069                                         printk(" %02x", *bp++);
2070                                 }
2071                         }
2072                         printk("\n");
2073                         if (pp->length > 64)
2074                                 printk("                 ... (length = %d)\n",
2075                                        pp->length);
2076                 }
2077         }
2078 }
2079 #endif
2080
2081 spinlock_t rtas_lock = SPIN_LOCK_UNLOCKED;
2082
2083 /* this can be called after setup -- Cort */
2084 int __openfirmware
2085 call_rtas(const char *service, int nargs, int nret,
2086           unsigned long *outputs, ...)
2087 {
2088         va_list list;
2089         int i;
2090         unsigned long s;
2091         struct device_node *rtas;
2092         int *tokp;
2093         union {
2094                 unsigned long words[16];
2095                 double align;
2096         } u;
2097
2098         rtas = find_devices("rtas");
2099         if (rtas == NULL)
2100                 return -1;
2101         tokp = (int *) get_property(rtas, service, NULL);
2102         if (tokp == NULL) {
2103                 printk(KERN_ERR "No RTAS service called %s\n", service);
2104                 return -1;
2105         }
2106         u.words[0] = *tokp;
2107         u.words[1] = nargs;
2108         u.words[2] = nret;
2109         va_start(list, outputs);
2110         for (i = 0; i < nargs; ++i)
2111                 u.words[i+3] = va_arg(list, unsigned long);
2112         va_end(list);
2113
2114         spin_lock_irqsave(&rtas_lock, s);
2115         enter_rtas((void *)__pa(&u));
2116         spin_unlock_irqrestore(&rtas_lock, s);
2117
2118         if (nret > 1 && outputs != NULL)
2119                 for (i = 0; i < nret-1; ++i)
2120                         outputs[i] = u.words[i+nargs+4];
2121         return u.words[nargs+3];
2122 }
2123
2124 void __init
2125 abort()
2126 {
2127 #ifdef CONFIG_XMON
2128         xmon(NULL);
2129 #endif
2130         for (;;)
2131                 prom_exit();
2132 }
2133
2134 #ifdef CONFIG_BOOTX_TEXT
2135
2136 /* Here's a small text engine to use during early boot or for debugging purposes
2137  * 
2138  * todo:
2139  * 
2140  *  - build some kind of vgacon with it to enable early printk
2141  *  - move to a separate file
2142  *  - add a few video driver hooks to keep in sync with display
2143  *    changes.
2144  */
2145
2146 void
2147 map_bootx_text(void)
2148 {
2149         unsigned long base, offset, size;
2150         if (disp_bi == 0)
2151                 return;
2152         base = ((unsigned long) disp_bi->dispDeviceBase) & 0xFFFFF000UL;
2153         offset = ((unsigned long) disp_bi->dispDeviceBase) - base;
2154         size = disp_bi->dispDeviceRowBytes * disp_bi->dispDeviceRect[3] + offset
2155                 + disp_bi->dispDeviceRect[0];
2156         disp_bi->logicalDisplayBase = ioremap(base, size);
2157         if (disp_bi->logicalDisplayBase == 0)
2158                 return;
2159         disp_bi->logicalDisplayBase += offset;
2160         bootx_text_mapped = 1;
2161 }
2162
2163 /* Calc the base address of a given point (x,y) */
2164 static unsigned char * __pmac
2165 calc_base(boot_infos_t *bi, int x, int y)
2166 {
2167         unsigned char *base;
2168
2169         base = bi->logicalDisplayBase;
2170         if (base == 0)
2171                 base = bi->dispDeviceBase;
2172         base += (x + bi->dispDeviceRect[0]) * (bi->dispDeviceDepth >> 3);
2173         base += (y + bi->dispDeviceRect[1]) * bi->dispDeviceRowBytes;
2174         return base;
2175 }
2176
2177 /* Adjust the display to a new resolution */
2178 void __openfirmware
2179 bootx_update_display(unsigned long phys, int width, int height,
2180                      int depth, int pitch)
2181 {
2182         if (disp_bi == 0)
2183                 return;
2184         /* check it's the same frame buffer (within 64MB) */
2185         if ((phys ^ (unsigned long)disp_bi->dispDeviceBase) & 0xfc000000) {
2186                 return;
2187         }
2188
2189         disp_bi->dispDeviceBase = (__u8 *) phys;
2190         disp_bi->dispDeviceRect[0] = 0;
2191         disp_bi->dispDeviceRect[1] = 0;
2192         disp_bi->dispDeviceRect[2] = width;
2193         disp_bi->dispDeviceRect[3] = height;
2194         disp_bi->dispDeviceDepth = depth;
2195         disp_bi->dispDeviceRowBytes = pitch;
2196         if (bootx_text_mapped) {
2197                 iounmap(disp_bi->logicalDisplayBase);
2198                 bootx_text_mapped = 0;
2199         }
2200         map_bootx_text();
2201         g_loc_X = 0;
2202         g_loc_Y = 0;
2203         g_max_loc_X = width / 8;
2204         g_max_loc_Y = height / 16;
2205 }
2206
2207 static void __pmac
2208 clearscreen(void)
2209 {
2210         unsigned long offset    = reloc_offset();
2211         boot_infos_t* bi        = PTRRELOC(RELOC(disp_bi));
2212         unsigned long *base     = (unsigned long *)calc_base(bi, 0, 0);
2213         unsigned long width     = ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
2214                                         (bi->dispDeviceDepth >> 3)) >> 2;
2215         int i,j;
2216         
2217         for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1]); i++)
2218         {
2219                 unsigned long *ptr = base;
2220                 for(j=width; j; --j)
2221                         *(ptr++) = 0;
2222                 base += (bi->dispDeviceRowBytes >> 2);
2223         }
2224 }
2225
2226 __inline__ void dcbst(const void* addr)
2227 {
2228         __asm__ __volatile__ ("dcbst 0,%0" :: "r" (addr));
2229 }
2230
2231 static void __pmac
2232 flushscreen(void)
2233 {
2234         unsigned long offset    = reloc_offset();
2235         boot_infos_t* bi        = PTRRELOC(RELOC(disp_bi));
2236         unsigned long *base     = (unsigned long *)calc_base(bi, 0, 0);
2237         unsigned long width     = ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
2238                                         (bi->dispDeviceDepth >> 3)) >> 2;
2239         int i,j;
2240         
2241         for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1]); i++)
2242         {
2243                 unsigned long *ptr = base;
2244                 for(j=width; j>0; j-=8) {
2245                         dcbst(ptr);
2246                         ptr += 8;
2247                 }
2248                 base += (bi->dispDeviceRowBytes >> 2);
2249         }
2250 }
2251
2252 #ifndef NO_SCROLL
2253 static void __pmac
2254 scrollscreen(void)
2255 {
2256         unsigned long offset            = reloc_offset();
2257         boot_infos_t* bi                = PTRRELOC(RELOC(disp_bi));
2258         unsigned long *src              = (unsigned long *)calc_base(bi,0,16);
2259         unsigned long *dst              = (unsigned long *)calc_base(bi,0,0);
2260         unsigned long width             = ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
2261                                                 (bi->dispDeviceDepth >> 3)) >> 2;
2262         int i,j;
2263         
2264 #ifdef CONFIG_ADB_PMU
2265         pmu_suspend();  /* PMU will not shut us down ! */
2266 #endif
2267         for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1] - 16); i++)
2268         {
2269                 unsigned long *src_ptr = src;
2270                 unsigned long *dst_ptr = dst;
2271                 for(j=width; j; --j)
2272                         *(dst_ptr++) = *(src_ptr++);
2273                 src += (bi->dispDeviceRowBytes >> 2);
2274                 dst += (bi->dispDeviceRowBytes >> 2);
2275         }
2276         for (i=0; i<16; i++)
2277         {
2278                 unsigned long *dst_ptr = dst;
2279                 for(j=width; j; --j)
2280                         *(dst_ptr++) = 0;
2281                 dst += (bi->dispDeviceRowBytes >> 2);
2282         }
2283 #ifdef CONFIG_ADB_PMU
2284         pmu_resume();   /* PMU will not shut us down ! */
2285 #endif
2286 }
2287 #endif /* ndef NO_SCROLL */
2288
2289 void __pmac
2290 prom_drawchar(char c)
2291 {
2292         unsigned long offset = reloc_offset();
2293         int cline = 0, x;
2294
2295         if (!RELOC(bootx_text_mapped))
2296                 return;
2297
2298         switch (c) {
2299         case '\b':
2300                 if (RELOC(g_loc_X) > 0)
2301                         --RELOC(g_loc_X);
2302                 break;
2303         case '\t':
2304                 RELOC(g_loc_X) = (RELOC(g_loc_X) & -8) + 8;
2305                 break;
2306         case '\r':
2307                 RELOC(g_loc_X) = 0;
2308                 break;
2309         case '\n':
2310                 RELOC(g_loc_X) = 0;
2311                 RELOC(g_loc_Y)++;
2312                 cline = 1;
2313                 break;
2314         default:
2315                 draw_byte(c, RELOC(g_loc_X)++, RELOC(g_loc_Y));
2316         }
2317         if (RELOC(g_loc_X) >= RELOC(g_max_loc_X)) {
2318                 RELOC(g_loc_X) = 0;
2319                 RELOC(g_loc_Y)++;
2320                 cline = 1;
2321         }
2322 #ifndef NO_SCROLL
2323         while (RELOC(g_loc_Y) >= RELOC(g_max_loc_Y)) {
2324                 scrollscreen();
2325                 RELOC(g_loc_Y)--;
2326         }
2327 #else
2328         /* wrap around from bottom to top of screen so we don't
2329            waste time scrolling each line.  -- paulus. */
2330         if (RELOC(g_loc_Y) >= RELOC(g_max_loc_Y))
2331                 RELOC(g_loc_Y) = 0;
2332         if (cline) {
2333                 for (x = 0; x < RELOC(g_max_loc_X); ++x)
2334                         draw_byte(' ', x, RELOC(g_loc_Y));
2335         }
2336 #endif
2337 }
2338
2339 void __pmac
2340 prom_drawstring(const char *c)
2341 {
2342         unsigned long offset    = reloc_offset();
2343
2344         if (!RELOC(bootx_text_mapped))
2345                 return;
2346         while (*c)
2347                 prom_drawchar(*c++);
2348 }
2349
2350 void __pmac
2351 prom_drawhex(unsigned long v)
2352 {
2353         static char hex_table[] = "0123456789abcdef";
2354         unsigned long offset    = reloc_offset();
2355         
2356         if (!RELOC(bootx_text_mapped))
2357                 return;
2358         prom_drawchar(RELOC(hex_table)[(v >> 28) & 0x0000000FUL]);
2359         prom_drawchar(RELOC(hex_table)[(v >> 24) & 0x0000000FUL]);
2360         prom_drawchar(RELOC(hex_table)[(v >> 20) & 0x0000000FUL]);
2361         prom_drawchar(RELOC(hex_table)[(v >> 16) & 0x0000000FUL]);
2362         prom_drawchar(RELOC(hex_table)[(v >> 12) & 0x0000000FUL]);
2363         prom_drawchar(RELOC(hex_table)[(v >>  8) & 0x0000000FUL]);
2364         prom_drawchar(RELOC(hex_table)[(v >>  4) & 0x0000000FUL]);
2365         prom_drawchar(RELOC(hex_table)[(v >>  0) & 0x0000000FUL]);
2366 }
2367
2368 static void __pmac
2369 draw_byte(unsigned char c, long locX, long locY)
2370 {
2371         unsigned long offset    = reloc_offset();
2372         boot_infos_t* bi        = PTRRELOC(RELOC(disp_bi));
2373         unsigned char *base     = calc_base(bi, locX << 3, locY << 4);
2374         unsigned char *font     = &RELOC(vga_font)[((unsigned long)c) * 16];
2375         int rb                  = bi->dispDeviceRowBytes;
2376         
2377         switch(bi->dispDeviceDepth) {
2378                 case 32:
2379                         draw_byte_32(font, (unsigned long *)base, rb);
2380                         break;
2381                 case 16:
2382                         draw_byte_16(font, (unsigned long *)base, rb);
2383                         break;
2384                 case 8:
2385                         draw_byte_8(font, (unsigned long *)base, rb);
2386                         break;
2387                 default:
2388                         break;
2389         }
2390 }
2391
2392 static unsigned long expand_bits_8[16] __pmacdata  = {
2393         0x00000000,
2394         0x000000ff,
2395         0x0000ff00,
2396         0x0000ffff,
2397         0x00ff0000,
2398         0x00ff00ff,
2399         0x00ffff00,
2400         0x00ffffff,
2401         0xff000000,
2402         0xff0000ff,
2403         0xff00ff00,
2404         0xff00ffff,
2405         0xffff0000,
2406         0xffff00ff,
2407         0xffffff00,
2408         0xffffffff
2409 };
2410
2411 static unsigned long expand_bits_16[4] __pmacdata = {
2412         0x00000000,
2413         0x0000ffff,
2414         0xffff0000,
2415         0xffffffff
2416 };
2417
2418 static void __pmac
2419 draw_byte_32(unsigned char *font, unsigned long *base, int rb)
2420 {
2421         int l, bits;    
2422         int fg = 0xFFFFFFFFUL;
2423         int bg = 0x00000000UL;
2424         
2425         for (l = 0; l < 16; ++l)
2426         {
2427                 bits = *font++;
2428                 base[0] = (-(bits >> 7) & fg) ^ bg;
2429                 base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
2430                 base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
2431                 base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
2432                 base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
2433                 base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
2434                 base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
2435                 base[7] = (-(bits & 1) & fg) ^ bg;
2436                 base = (unsigned long *) ((char *)base + rb);
2437         }
2438 }
2439
2440 static void __pmac
2441 draw_byte_16(unsigned char *font, unsigned long *base, int rb)
2442 {
2443         int l, bits;    
2444         int fg = 0xFFFFFFFFUL;
2445         int bg = 0x00000000UL;
2446         unsigned long offset = reloc_offset();
2447         unsigned long *eb = RELOC(expand_bits_16);
2448
2449         for (l = 0; l < 16; ++l)
2450         {
2451                 bits = *font++;
2452                 base[0] = (eb[bits >> 6] & fg) ^ bg;
2453                 base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
2454                 base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
2455                 base[3] = (eb[bits & 3] & fg) ^ bg;
2456                 base = (unsigned long *) ((char *)base + rb);
2457         }
2458 }
2459
2460 static void __pmac
2461 draw_byte_8(unsigned char *font, unsigned long *base, int rb)
2462 {
2463         int l, bits;    
2464         int fg = 0x0F0F0F0FUL;
2465         int bg = 0x00000000UL;
2466         unsigned long offset = reloc_offset();
2467         unsigned long *eb = RELOC(expand_bits_8);
2468
2469         for (l = 0; l < 16; ++l)
2470         {
2471                 bits = *font++;
2472                 base[0] = (eb[bits >> 4] & fg) ^ bg;
2473                 base[1] = (eb[bits & 0xf] & fg) ^ bg;
2474                 base = (unsigned long *) ((char *)base + rb);
2475         }
2476 }
2477
2478 static unsigned char vga_font[cmapsz] __pmacdata = {
2479 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2480 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 
2481 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, 
2482 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 
2483 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 
2484 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 
2485 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 
2486 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
2487 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 
2488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 
2489 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 
2490 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
2491 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 
2492 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 
2493 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, 
2494 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 
2495 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 
2496 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 
2497 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, 
2498 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, 
2499 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 
2500 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 
2501 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, 
2502 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 
2503 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 
2504 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 
2505 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, 
2506 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 
2507 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 
2508 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2509 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 
2510 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 
2511 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
2512 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
2513 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2514 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2515 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 
2516 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 
2517 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2518 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2519 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 
2520 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 
2521 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2522 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2523 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 
2524 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 
2525 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 
2526 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 
2527 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 
2528 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 
2529 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 
2530 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
2531 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2532 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 
2533 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 
2534 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 
2535 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 
2536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 
2537 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2538 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 
2539 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 
2540 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2541 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2542 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 
2543 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 
2544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 
2545 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
2546 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 
2547 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 
2548 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 
2549 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 
2550 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
2551 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
2552 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 
2553 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
2554 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
2555 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 
2556 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 
2557 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2558 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 
2559 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 
2560 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 
2561 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 
2562 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 
2563 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 
2564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, 
2565 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 
2566 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
2567 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 
2568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 
2569 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, 
2570 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 
2571 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 
2572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 
2573 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 
2574 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, 
2575 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
2576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 
2577 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 
2578 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 
2579 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 
2580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 
2581 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7, 
2582 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 
2583 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 
2584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
2585 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 
2586 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 
2587 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 
2588 0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 
2589 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
2590 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
2591 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
2592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
2593 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 
2594 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 
2595 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 
2596 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 
2597 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 
2598 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
2599 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 
2600 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 
2601 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 
2602 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 
2603 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 
2604 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 
2605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 
2607 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 
2609 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, 
2610 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, 
2611 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 
2612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 
2613 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2614 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
2615 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 
2616 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 
2617 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, 
2618 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 
2619 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
2620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 
2621 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, 
2622 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 
2623 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
2624 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 
2625 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2626 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 
2627 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
2628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 
2629 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 
2630 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, 
2631 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 
2632 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 
2633 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 
2634 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 
2635 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
2636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 
2637 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2638 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, 
2639 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 
2640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 
2641 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 
2642 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 
2643 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 
2644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 
2645 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 
2646 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 
2647 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 
2649 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 
2650 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, 
2651 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
2652 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 
2653 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 
2654 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
2655 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 
2656 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 
2657 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 
2658 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
2659 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 
2660 0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 
2661 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 
2662 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
2663 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 
2664 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 
2665 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 
2666 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
2667 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
2668 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 
2669 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, 
2670 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
2671 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 
2672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 
2673 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, 
2674 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, 
2675 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
2676 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 
2677 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 
2678 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
2679 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
2680 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 
2681 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 
2682 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, 
2683 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
2684 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
2685 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 
2686 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 
2687 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 
2688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 
2689 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 
2690 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, 
2691 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 
2692 0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 
2693 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 
2694 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
2695 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
2696 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 
2697 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 
2698 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 
2699 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 
2700 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 
2701 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 
2702 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2703 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 
2704 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 
2705 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
2706 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
2707 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 
2708 0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 
2709 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 
2710 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 
2711 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 
2712 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 
2713 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, 
2714 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 
2715 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 
2716 0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 
2717 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, 
2718 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
2719 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 
2720 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 
2721 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 
2722 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
2723 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 
2724 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 
2725 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 
2726 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
2727 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
2728 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 
2729 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
2730 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,