Merge commit 'upstream/master'
[pandora-kernel.git] / arch / powerpc / kernel / prom_init.c
1 /*
2  * Procedures for interfacing to Open Firmware.
3  *
4  * Paul Mackerras       August 1996.
5  * Copyright (C) 1996-2005 Paul Mackerras.
6  * 
7  *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
8  *    {engebret|bergner}@us.ibm.com 
9  *
10  *      This program is free software; you can redistribute it and/or
11  *      modify it under the terms of the GNU General Public License
12  *      as published by the Free Software Foundation; either version
13  *      2 of the License, or (at your option) any later version.
14  */
15
16 #undef DEBUG_PROM
17
18 #include <stdarg.h>
19 #include <linux/kernel.h>
20 #include <linux/string.h>
21 #include <linux/init.h>
22 #include <linux/threads.h>
23 #include <linux/spinlock.h>
24 #include <linux/types.h>
25 #include <linux/pci.h>
26 #include <linux/proc_fs.h>
27 #include <linux/stringify.h>
28 #include <linux/delay.h>
29 #include <linux/initrd.h>
30 #include <linux/bitops.h>
31 #include <asm/prom.h>
32 #include <asm/rtas.h>
33 #include <asm/page.h>
34 #include <asm/processor.h>
35 #include <asm/irq.h>
36 #include <asm/io.h>
37 #include <asm/smp.h>
38 #include <asm/system.h>
39 #include <asm/mmu.h>
40 #include <asm/pgtable.h>
41 #include <asm/pci.h>
42 #include <asm/iommu.h>
43 #include <asm/btext.h>
44 #include <asm/sections.h>
45 #include <asm/machdep.h>
46
47 #ifdef CONFIG_LOGO_LINUX_CLUT224
48 #include <linux/linux_logo.h>
49 extern const struct linux_logo logo_linux_clut224;
50 #endif
51
52 /*
53  * Properties whose value is longer than this get excluded from our
54  * copy of the device tree. This value does need to be big enough to
55  * ensure that we don't lose things like the interrupt-map property
56  * on a PCI-PCI bridge.
57  */
58 #define MAX_PROPERTY_LENGTH     (1UL * 1024 * 1024)
59
60 /*
61  * Eventually bump that one up
62  */
63 #define DEVTREE_CHUNK_SIZE      0x100000
64
65 /*
66  * This is the size of the local memory reserve map that gets copied
67  * into the boot params passed to the kernel. That size is totally
68  * flexible as the kernel just reads the list until it encounters an
69  * entry with size 0, so it can be changed without breaking binary
70  * compatibility
71  */
72 #define MEM_RESERVE_MAP_SIZE    8
73
74 /*
75  * prom_init() is called very early on, before the kernel text
76  * and data have been mapped to KERNELBASE.  At this point the code
77  * is running at whatever address it has been loaded at.
78  * On ppc32 we compile with -mrelocatable, which means that references
79  * to extern and static variables get relocated automatically.
80  * On ppc64 we have to relocate the references explicitly with
81  * RELOC.  (Note that strings count as static variables.)
82  *
83  * Because OF may have mapped I/O devices into the area starting at
84  * KERNELBASE, particularly on CHRP machines, we can't safely call
85  * OF once the kernel has been mapped to KERNELBASE.  Therefore all
86  * OF calls must be done within prom_init().
87  *
88  * ADDR is used in calls to call_prom.  The 4th and following
89  * arguments to call_prom should be 32-bit values.
90  * On ppc64, 64 bit values are truncated to 32 bits (and
91  * fortunately don't get interpreted as two arguments).
92  */
93 #ifdef CONFIG_PPC64
94 #define RELOC(x)        (*PTRRELOC(&(x)))
95 #define ADDR(x)         (u32) add_reloc_offset((unsigned long)(x))
96 #define OF_WORKAROUNDS  0
97 #else
98 #define RELOC(x)        (x)
99 #define ADDR(x)         (u32) (x)
100 #define OF_WORKAROUNDS  of_workarounds
101 int of_workarounds;
102 #endif
103
104 #define OF_WA_CLAIM     1       /* do phys/virt claim separately, then map */
105 #define OF_WA_LONGTRAIL 2       /* work around longtrail bugs */
106
107 #define PROM_BUG() do {                                         \
108         prom_printf("kernel BUG at %s line 0x%x!\n",            \
109                     RELOC(__FILE__), __LINE__);                 \
110         __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR);       \
111 } while (0)
112
113 #ifdef DEBUG_PROM
114 #define prom_debug(x...)        prom_printf(x)
115 #else
116 #define prom_debug(x...)
117 #endif
118
119
120 typedef u32 prom_arg_t;
121
122 struct prom_args {
123         u32 service;
124         u32 nargs;
125         u32 nret;
126         prom_arg_t args[10];
127 };
128
129 struct prom_t {
130         ihandle root;
131         phandle chosen;
132         int cpu;
133         ihandle stdout;
134         ihandle mmumap;
135         ihandle memory;
136 };
137
138 struct mem_map_entry {
139         u64     base;
140         u64     size;
141 };
142
143 typedef u32 cell_t;
144
145 extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);
146
147 #ifdef CONFIG_PPC64
148 extern int enter_prom(struct prom_args *args, unsigned long entry);
149 #else
150 static inline int enter_prom(struct prom_args *args, unsigned long entry)
151 {
152         return ((int (*)(struct prom_args *))entry)(args);
153 }
154 #endif
155
156 extern void copy_and_flush(unsigned long dest, unsigned long src,
157                            unsigned long size, unsigned long offset);
158
159 /* prom structure */
160 static struct prom_t __initdata prom;
161
162 static unsigned long prom_entry __initdata;
163
164 #define PROM_SCRATCH_SIZE 256
165
166 static char __initdata of_stdout_device[256];
167 static char __initdata prom_scratch[PROM_SCRATCH_SIZE];
168
169 static unsigned long __initdata dt_header_start;
170 static unsigned long __initdata dt_struct_start, dt_struct_end;
171 static unsigned long __initdata dt_string_start, dt_string_end;
172
173 static unsigned long __initdata prom_initrd_start, prom_initrd_end;
174
175 #ifdef CONFIG_PPC64
176 static int __initdata prom_iommu_force_on;
177 static int __initdata prom_iommu_off;
178 static unsigned long __initdata prom_tce_alloc_start;
179 static unsigned long __initdata prom_tce_alloc_end;
180 #endif
181
182 /* Platforms codes are now obsolete in the kernel. Now only used within this
183  * file and ultimately gone too. Feel free to change them if you need, they
184  * are not shared with anything outside of this file anymore
185  */
186 #define PLATFORM_PSERIES        0x0100
187 #define PLATFORM_PSERIES_LPAR   0x0101
188 #define PLATFORM_LPAR           0x0001
189 #define PLATFORM_POWERMAC       0x0400
190 #define PLATFORM_GENERIC        0x0500
191
192 static int __initdata of_platform;
193
194 static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
195
196 static unsigned long __initdata alloc_top;
197 static unsigned long __initdata alloc_top_high;
198 static unsigned long __initdata alloc_bottom;
199 static unsigned long __initdata rmo_top;
200 static unsigned long __initdata ram_top;
201
202 static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
203 static int __initdata mem_reserve_cnt;
204
205 static cell_t __initdata regbuf[1024];
206
207
208 #define MAX_CPU_THREADS 2
209
210 /*
211  * Error results ... some OF calls will return "-1" on error, some
212  * will return 0, some will return either. To simplify, here are
213  * macros to use with any ihandle or phandle return value to check if
214  * it is valid
215  */
216
217 #define PROM_ERROR              (-1u)
218 #define PHANDLE_VALID(p)        ((p) != 0 && (p) != PROM_ERROR)
219 #define IHANDLE_VALID(i)        ((i) != 0 && (i) != PROM_ERROR)
220
221
222 /* This is the one and *ONLY* place where we actually call open
223  * firmware.
224  */
225
226 static int __init call_prom(const char *service, int nargs, int nret, ...)
227 {
228         int i;
229         struct prom_args args;
230         va_list list;
231
232         args.service = ADDR(service);
233         args.nargs = nargs;
234         args.nret = nret;
235
236         va_start(list, nret);
237         for (i = 0; i < nargs; i++)
238                 args.args[i] = va_arg(list, prom_arg_t);
239         va_end(list);
240
241         for (i = 0; i < nret; i++)
242                 args.args[nargs+i] = 0;
243
244         if (enter_prom(&args, RELOC(prom_entry)) < 0)
245                 return PROM_ERROR;
246
247         return (nret > 0) ? args.args[nargs] : 0;
248 }
249
250 static int __init call_prom_ret(const char *service, int nargs, int nret,
251                                 prom_arg_t *rets, ...)
252 {
253         int i;
254         struct prom_args args;
255         va_list list;
256
257         args.service = ADDR(service);
258         args.nargs = nargs;
259         args.nret = nret;
260
261         va_start(list, rets);
262         for (i = 0; i < nargs; i++)
263                 args.args[i] = va_arg(list, prom_arg_t);
264         va_end(list);
265
266         for (i = 0; i < nret; i++)
267                 args.args[nargs+i] = 0;
268
269         if (enter_prom(&args, RELOC(prom_entry)) < 0)
270                 return PROM_ERROR;
271
272         if (rets != NULL)
273                 for (i = 1; i < nret; ++i)
274                         rets[i-1] = args.args[nargs+i];
275
276         return (nret > 0) ? args.args[nargs] : 0;
277 }
278
279
280 static void __init prom_print(const char *msg)
281 {
282         const char *p, *q;
283         struct prom_t *_prom = &RELOC(prom);
284
285         if (_prom->stdout == 0)
286                 return;
287
288         for (p = msg; *p != 0; p = q) {
289                 for (q = p; *q != 0 && *q != '\n'; ++q)
290                         ;
291                 if (q > p)
292                         call_prom("write", 3, 1, _prom->stdout, p, q - p);
293                 if (*q == 0)
294                         break;
295                 ++q;
296                 call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2);
297         }
298 }
299
300
301 static void __init prom_print_hex(unsigned long val)
302 {
303         int i, nibbles = sizeof(val)*2;
304         char buf[sizeof(val)*2+1];
305         struct prom_t *_prom = &RELOC(prom);
306
307         for (i = nibbles-1;  i >= 0;  i--) {
308                 buf[i] = (val & 0xf) + '0';
309                 if (buf[i] > '9')
310                         buf[i] += ('a'-'0'-10);
311                 val >>= 4;
312         }
313         buf[nibbles] = '\0';
314         call_prom("write", 3, 1, _prom->stdout, buf, nibbles);
315 }
316
317
318 static void __init prom_printf(const char *format, ...)
319 {
320         const char *p, *q, *s;
321         va_list args;
322         unsigned long v;
323         struct prom_t *_prom = &RELOC(prom);
324
325         va_start(args, format);
326 #ifdef CONFIG_PPC64
327         format = PTRRELOC(format);
328 #endif
329         for (p = format; *p != 0; p = q) {
330                 for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
331                         ;
332                 if (q > p)
333                         call_prom("write", 3, 1, _prom->stdout, p, q - p);
334                 if (*q == 0)
335                         break;
336                 if (*q == '\n') {
337                         ++q;
338                         call_prom("write", 3, 1, _prom->stdout,
339                                   ADDR("\r\n"), 2);
340                         continue;
341                 }
342                 ++q;
343                 if (*q == 0)
344                         break;
345                 switch (*q) {
346                 case 's':
347                         ++q;
348                         s = va_arg(args, const char *);
349                         prom_print(s);
350                         break;
351                 case 'x':
352                         ++q;
353                         v = va_arg(args, unsigned long);
354                         prom_print_hex(v);
355                         break;
356                 }
357         }
358 }
359
360
361 static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
362                                 unsigned long align)
363 {
364         struct prom_t *_prom = &RELOC(prom);
365
366         if (align == 0 && (OF_WORKAROUNDS & OF_WA_CLAIM)) {
367                 /*
368                  * Old OF requires we claim physical and virtual separately
369                  * and then map explicitly (assuming virtual mode)
370                  */
371                 int ret;
372                 prom_arg_t result;
373
374                 ret = call_prom_ret("call-method", 5, 2, &result,
375                                     ADDR("claim"), _prom->memory,
376                                     align, size, virt);
377                 if (ret != 0 || result == -1)
378                         return -1;
379                 ret = call_prom_ret("call-method", 5, 2, &result,
380                                     ADDR("claim"), _prom->mmumap,
381                                     align, size, virt);
382                 if (ret != 0) {
383                         call_prom("call-method", 4, 1, ADDR("release"),
384                                   _prom->memory, size, virt);
385                         return -1;
386                 }
387                 /* the 0x12 is M (coherence) + PP == read/write */
388                 call_prom("call-method", 6, 1,
389                           ADDR("map"), _prom->mmumap, 0x12, size, virt, virt);
390                 return virt;
391         }
392         return call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
393                          (prom_arg_t)align);
394 }
395
396 static void __init __attribute__((noreturn)) prom_panic(const char *reason)
397 {
398 #ifdef CONFIG_PPC64
399         reason = PTRRELOC(reason);
400 #endif
401         prom_print(reason);
402         /* Do not call exit because it clears the screen on pmac
403          * it also causes some sort of double-fault on early pmacs */
404         if (RELOC(of_platform) == PLATFORM_POWERMAC)
405                 asm("trap\n");
406
407         /* ToDo: should put up an SRC here on p/iSeries */
408         call_prom("exit", 0, 0);
409
410         for (;;)                        /* should never get here */
411                 ;
412 }
413
414
415 static int __init prom_next_node(phandle *nodep)
416 {
417         phandle node;
418
419         if ((node = *nodep) != 0
420             && (*nodep = call_prom("child", 1, 1, node)) != 0)
421                 return 1;
422         if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
423                 return 1;
424         for (;;) {
425                 if ((node = call_prom("parent", 1, 1, node)) == 0)
426                         return 0;
427                 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
428                         return 1;
429         }
430 }
431
432 static int inline prom_getprop(phandle node, const char *pname,
433                                void *value, size_t valuelen)
434 {
435         return call_prom("getprop", 4, 1, node, ADDR(pname),
436                          (u32)(unsigned long) value, (u32) valuelen);
437 }
438
439 static int inline prom_getproplen(phandle node, const char *pname)
440 {
441         return call_prom("getproplen", 2, 1, node, ADDR(pname));
442 }
443
444 static void add_string(char **str, const char *q)
445 {
446         char *p = *str;
447
448         while (*q)
449                 *p++ = *q++;
450         *p++ = ' ';
451         *str = p;
452 }
453
454 static char *tohex(unsigned int x)
455 {
456         static char digits[] = "0123456789abcdef";
457         static char result[9];
458         int i;
459
460         result[8] = 0;
461         i = 8;
462         do {
463                 --i;
464                 result[i] = digits[x & 0xf];
465                 x >>= 4;
466         } while (x != 0 && i > 0);
467         return &result[i];
468 }
469
470 static int __init prom_setprop(phandle node, const char *nodename,
471                                const char *pname, void *value, size_t valuelen)
472 {
473         char cmd[256], *p;
474
475         if (!(OF_WORKAROUNDS & OF_WA_LONGTRAIL))
476                 return call_prom("setprop", 4, 1, node, ADDR(pname),
477                                  (u32)(unsigned long) value, (u32) valuelen);
478
479         /* gah... setprop doesn't work on longtrail, have to use interpret */
480         p = cmd;
481         add_string(&p, "dev");
482         add_string(&p, nodename);
483         add_string(&p, tohex((u32)(unsigned long) value));
484         add_string(&p, tohex(valuelen));
485         add_string(&p, tohex(ADDR(pname)));
486         add_string(&p, tohex(strlen(RELOC(pname))));
487         add_string(&p, "property");
488         *p = 0;
489         return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
490 }
491
492 /* We can't use the standard versions because of RELOC headaches. */
493 #define isxdigit(c)     (('0' <= (c) && (c) <= '9') \
494                          || ('a' <= (c) && (c) <= 'f') \
495                          || ('A' <= (c) && (c) <= 'F'))
496
497 #define isdigit(c)      ('0' <= (c) && (c) <= '9')
498 #define islower(c)      ('a' <= (c) && (c) <= 'z')
499 #define toupper(c)      (islower(c) ? ((c) - 'a' + 'A') : (c))
500
501 unsigned long prom_strtoul(const char *cp, const char **endp)
502 {
503         unsigned long result = 0, base = 10, value;
504
505         if (*cp == '0') {
506                 base = 8;
507                 cp++;
508                 if (toupper(*cp) == 'X') {
509                         cp++;
510                         base = 16;
511                 }
512         }
513
514         while (isxdigit(*cp) &&
515                (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
516                 result = result * base + value;
517                 cp++;
518         }
519
520         if (endp)
521                 *endp = cp;
522
523         return result;
524 }
525
526 unsigned long prom_memparse(const char *ptr, const char **retptr)
527 {
528         unsigned long ret = prom_strtoul(ptr, retptr);
529         int shift = 0;
530
531         /*
532          * We can't use a switch here because GCC *may* generate a
533          * jump table which won't work, because we're not running at
534          * the address we're linked at.
535          */
536         if ('G' == **retptr || 'g' == **retptr)
537                 shift = 30;
538
539         if ('M' == **retptr || 'm' == **retptr)
540                 shift = 20;
541
542         if ('K' == **retptr || 'k' == **retptr)
543                 shift = 10;
544
545         if (shift) {
546                 ret <<= shift;
547                 (*retptr)++;
548         }
549
550         return ret;
551 }
552
553 /*
554  * Early parsing of the command line passed to the kernel, used for
555  * "mem=x" and the options that affect the iommu
556  */
557 static void __init early_cmdline_parse(void)
558 {
559         struct prom_t *_prom = &RELOC(prom);
560 #ifdef CONFIG_PPC64
561         const char *opt;
562 #endif
563         char *p;
564         int l = 0;
565
566         RELOC(prom_cmd_line[0]) = 0;
567         p = RELOC(prom_cmd_line);
568         if ((long)_prom->chosen > 0)
569                 l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
570 #ifdef CONFIG_CMDLINE
571         if (l <= 0 || p[0] == '\0') /* dbl check */
572                 strlcpy(RELOC(prom_cmd_line),
573                         RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line));
574 #endif /* CONFIG_CMDLINE */
575         prom_printf("command line: %s\n", RELOC(prom_cmd_line));
576
577 #ifdef CONFIG_PPC64
578         opt = strstr(RELOC(prom_cmd_line), RELOC("iommu="));
579         if (opt) {
580                 prom_printf("iommu opt is: %s\n", opt);
581                 opt += 6;
582                 while (*opt && *opt == ' ')
583                         opt++;
584                 if (!strncmp(opt, RELOC("off"), 3))
585                         RELOC(prom_iommu_off) = 1;
586                 else if (!strncmp(opt, RELOC("force"), 5))
587                         RELOC(prom_iommu_force_on) = 1;
588         }
589 #endif
590 }
591
592 #ifdef CONFIG_PPC_PSERIES
593 /*
594  * There are two methods for telling firmware what our capabilities are.
595  * Newer machines have an "ibm,client-architecture-support" method on the
596  * root node.  For older machines, we have to call the "process-elf-header"
597  * method in the /packages/elf-loader node, passing it a fake 32-bit
598  * ELF header containing a couple of PT_NOTE sections that contain
599  * structures that contain various information.
600  */
601
602 /*
603  * New method - extensible architecture description vector.
604  *
605  * Because the description vector contains a mix of byte and word
606  * values, we declare it as an unsigned char array, and use this
607  * macro to put word values in.
608  */
609 #define W(x)    ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \
610                 ((x) >> 8) & 0xff, (x) & 0xff
611
612 /* Option vector bits - generic bits in byte 1 */
613 #define OV_IGNORE               0x80    /* ignore this vector */
614 #define OV_CESSATION_POLICY     0x40    /* halt if unsupported option present*/
615
616 /* Option vector 1: processor architectures supported */
617 #define OV1_PPC_2_00            0x80    /* set if we support PowerPC 2.00 */
618 #define OV1_PPC_2_01            0x40    /* set if we support PowerPC 2.01 */
619 #define OV1_PPC_2_02            0x20    /* set if we support PowerPC 2.02 */
620 #define OV1_PPC_2_03            0x10    /* set if we support PowerPC 2.03 */
621 #define OV1_PPC_2_04            0x08    /* set if we support PowerPC 2.04 */
622 #define OV1_PPC_2_05            0x04    /* set if we support PowerPC 2.05 */
623 #define OV1_PPC_2_06            0x02    /* set if we support PowerPC 2.06 */
624
625 /* Option vector 2: Open Firmware options supported */
626 #define OV2_REAL_MODE           0x20    /* set if we want OF in real mode */
627
628 /* Option vector 3: processor options supported */
629 #define OV3_FP                  0x80    /* floating point */
630 #define OV3_VMX                 0x40    /* VMX/Altivec */
631 #define OV3_DFP                 0x20    /* decimal FP */
632
633 /* Option vector 5: PAPR/OF options supported */
634 #define OV5_LPAR                0x80    /* logical partitioning supported */
635 #define OV5_SPLPAR              0x40    /* shared-processor LPAR supported */
636 /* ibm,dynamic-reconfiguration-memory property supported */
637 #define OV5_DRCONF_MEMORY       0x20
638 #define OV5_LARGE_PAGES         0x10    /* large pages supported */
639 #define OV5_DONATE_DEDICATE_CPU 0x02    /* donate dedicated CPU support */
640 /* PCIe/MSI support.  Without MSI full PCIe is not supported */
641 #ifdef CONFIG_PCI_MSI
642 #define OV5_MSI                 0x01    /* PCIe/MSI support */
643 #else
644 #define OV5_MSI                 0x00
645 #endif /* CONFIG_PCI_MSI */
646 #ifdef CONFIG_PPC_SMLPAR
647 #define OV5_CMO                 0x80    /* Cooperative Memory Overcommitment */
648 #else
649 #define OV5_CMO                 0x00
650 #endif
651
652 /*
653  * The architecture vector has an array of PVR mask/value pairs,
654  * followed by # option vectors - 1, followed by the option vectors.
655  */
656 static unsigned char ibm_architecture_vec[] = {
657         W(0xfffe0000), W(0x003a0000),   /* POWER5/POWER5+ */
658         W(0xffff0000), W(0x003e0000),   /* POWER6 */
659         W(0xffff0000), W(0x003f0000),   /* POWER7 */
660         W(0xffffffff), W(0x0f000003),   /* all 2.06-compliant */
661         W(0xffffffff), W(0x0f000002),   /* all 2.05-compliant */
662         W(0xfffffffe), W(0x0f000001),   /* all 2.04-compliant and earlier */
663         5 - 1,                          /* 5 option vectors */
664
665         /* option vector 1: processor architectures supported */
666         3 - 2,                          /* length */
667         0,                              /* don't ignore, don't halt */
668         OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
669         OV1_PPC_2_04 | OV1_PPC_2_05 | OV1_PPC_2_06,
670
671         /* option vector 2: Open Firmware options supported */
672         34 - 2,                         /* length */
673         OV2_REAL_MODE,
674         0, 0,
675         W(0xffffffff),                  /* real_base */
676         W(0xffffffff),                  /* real_size */
677         W(0xffffffff),                  /* virt_base */
678         W(0xffffffff),                  /* virt_size */
679         W(0xffffffff),                  /* load_base */
680         W(64),                          /* 128MB min RMA */
681         W(0xffffffff),                  /* full client load */
682         0,                              /* min RMA percentage of total RAM */
683         48,                             /* max log_2(hash table size) */
684
685         /* option vector 3: processor options supported */
686         3 - 2,                          /* length */
687         0,                              /* don't ignore, don't halt */
688         OV3_FP | OV3_VMX | OV3_DFP,
689
690         /* option vector 4: IBM PAPR implementation */
691         2 - 2,                          /* length */
692         0,                              /* don't halt */
693
694         /* option vector 5: PAPR/OF options */
695         5 - 2,                          /* length */
696         0,                              /* don't ignore, don't halt */
697         OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY |
698         OV5_DONATE_DEDICATE_CPU | OV5_MSI,
699         0,
700         OV5_CMO,
701 };
702
703 /* Old method - ELF header with PT_NOTE sections */
704 static struct fake_elf {
705         Elf32_Ehdr      elfhdr;
706         Elf32_Phdr      phdr[2];
707         struct chrpnote {
708                 u32     namesz;
709                 u32     descsz;
710                 u32     type;
711                 char    name[8];        /* "PowerPC" */
712                 struct chrpdesc {
713                         u32     real_mode;
714                         u32     real_base;
715                         u32     real_size;
716                         u32     virt_base;
717                         u32     virt_size;
718                         u32     load_base;
719                 } chrpdesc;
720         } chrpnote;
721         struct rpanote {
722                 u32     namesz;
723                 u32     descsz;
724                 u32     type;
725                 char    name[24];       /* "IBM,RPA-Client-Config" */
726                 struct rpadesc {
727                         u32     lpar_affinity;
728                         u32     min_rmo_size;
729                         u32     min_rmo_percent;
730                         u32     max_pft_size;
731                         u32     splpar;
732                         u32     min_load;
733                         u32     new_mem_def;
734                         u32     ignore_me;
735                 } rpadesc;
736         } rpanote;
737 } fake_elf = {
738         .elfhdr = {
739                 .e_ident = { 0x7f, 'E', 'L', 'F',
740                              ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
741                 .e_type = ET_EXEC,      /* yeah right */
742                 .e_machine = EM_PPC,
743                 .e_version = EV_CURRENT,
744                 .e_phoff = offsetof(struct fake_elf, phdr),
745                 .e_phentsize = sizeof(Elf32_Phdr),
746                 .e_phnum = 2
747         },
748         .phdr = {
749                 [0] = {
750                         .p_type = PT_NOTE,
751                         .p_offset = offsetof(struct fake_elf, chrpnote),
752                         .p_filesz = sizeof(struct chrpnote)
753                 }, [1] = {
754                         .p_type = PT_NOTE,
755                         .p_offset = offsetof(struct fake_elf, rpanote),
756                         .p_filesz = sizeof(struct rpanote)
757                 }
758         },
759         .chrpnote = {
760                 .namesz = sizeof("PowerPC"),
761                 .descsz = sizeof(struct chrpdesc),
762                 .type = 0x1275,
763                 .name = "PowerPC",
764                 .chrpdesc = {
765                         .real_mode = ~0U,       /* ~0 means "don't care" */
766                         .real_base = ~0U,
767                         .real_size = ~0U,
768                         .virt_base = ~0U,
769                         .virt_size = ~0U,
770                         .load_base = ~0U
771                 },
772         },
773         .rpanote = {
774                 .namesz = sizeof("IBM,RPA-Client-Config"),
775                 .descsz = sizeof(struct rpadesc),
776                 .type = 0x12759999,
777                 .name = "IBM,RPA-Client-Config",
778                 .rpadesc = {
779                         .lpar_affinity = 0,
780                         .min_rmo_size = 64,     /* in megabytes */
781                         .min_rmo_percent = 0,
782                         .max_pft_size = 48,     /* 2^48 bytes max PFT size */
783                         .splpar = 1,
784                         .min_load = ~0U,
785                         .new_mem_def = 0
786                 }
787         }
788 };
789
790 static void __init prom_send_capabilities(void)
791 {
792         ihandle elfloader, root;
793         prom_arg_t ret;
794
795         root = call_prom("open", 1, 1, ADDR("/"));
796         if (root != 0) {
797                 /* try calling the ibm,client-architecture-support method */
798                 if (call_prom_ret("call-method", 3, 2, &ret,
799                                   ADDR("ibm,client-architecture-support"),
800                                   root,
801                                   ADDR(ibm_architecture_vec)) == 0) {
802                         /* the call exists... */
803                         if (ret)
804                                 prom_printf("WARNING: ibm,client-architecture"
805                                             "-support call FAILED!\n");
806                         call_prom("close", 1, 0, root);
807                         return;
808                 }
809                 call_prom("close", 1, 0, root);
810         }
811
812         /* no ibm,client-architecture-support call, try the old way */
813         elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
814         if (elfloader == 0) {
815                 prom_printf("couldn't open /packages/elf-loader\n");
816                 return;
817         }
818         call_prom("call-method", 3, 1, ADDR("process-elf-header"),
819                         elfloader, ADDR(&fake_elf));
820         call_prom("close", 1, 0, elfloader);
821 }
822 #endif
823
824 /*
825  * Memory allocation strategy... our layout is normally:
826  *
827  *  at 14Mb or more we have vmlinux, then a gap and initrd.  In some
828  *  rare cases, initrd might end up being before the kernel though.
829  *  We assume this won't override the final kernel at 0, we have no
830  *  provision to handle that in this version, but it should hopefully
831  *  never happen.
832  *
833  *  alloc_top is set to the top of RMO, eventually shrink down if the
834  *  TCEs overlap
835  *
836  *  alloc_bottom is set to the top of kernel/initrd
837  *
838  *  from there, allocations are done this way : rtas is allocated
839  *  topmost, and the device-tree is allocated from the bottom. We try
840  *  to grow the device-tree allocation as we progress. If we can't,
841  *  then we fail, we don't currently have a facility to restart
842  *  elsewhere, but that shouldn't be necessary.
843  *
844  *  Note that calls to reserve_mem have to be done explicitly, memory
845  *  allocated with either alloc_up or alloc_down isn't automatically
846  *  reserved.
847  */
848
849
850 /*
851  * Allocates memory in the RMO upward from the kernel/initrd
852  *
853  * When align is 0, this is a special case, it means to allocate in place
854  * at the current location of alloc_bottom or fail (that is basically
855  * extending the previous allocation). Used for the device-tree flattening
856  */
857 static unsigned long __init alloc_up(unsigned long size, unsigned long align)
858 {
859         unsigned long base = RELOC(alloc_bottom);
860         unsigned long addr = 0;
861
862         if (align)
863                 base = _ALIGN_UP(base, align);
864         prom_debug("alloc_up(%x, %x)\n", size, align);
865         if (RELOC(ram_top) == 0)
866                 prom_panic("alloc_up() called with mem not initialized\n");
867
868         if (align)
869                 base = _ALIGN_UP(RELOC(alloc_bottom), align);
870         else
871                 base = RELOC(alloc_bottom);
872
873         for(; (base + size) <= RELOC(alloc_top); 
874             base = _ALIGN_UP(base + 0x100000, align)) {
875                 prom_debug("    trying: 0x%x\n\r", base);
876                 addr = (unsigned long)prom_claim(base, size, 0);
877                 if (addr != PROM_ERROR && addr != 0)
878                         break;
879                 addr = 0;
880                 if (align == 0)
881                         break;
882         }
883         if (addr == 0)
884                 return 0;
885         RELOC(alloc_bottom) = addr;
886
887         prom_debug(" -> %x\n", addr);
888         prom_debug("  alloc_bottom : %x\n", RELOC(alloc_bottom));
889         prom_debug("  alloc_top    : %x\n", RELOC(alloc_top));
890         prom_debug("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
891         prom_debug("  rmo_top      : %x\n", RELOC(rmo_top));
892         prom_debug("  ram_top      : %x\n", RELOC(ram_top));
893
894         return addr;
895 }
896
897 /*
898  * Allocates memory downward, either from top of RMO, or if highmem
899  * is set, from the top of RAM.  Note that this one doesn't handle
900  * failures.  It does claim memory if highmem is not set.
901  */
902 static unsigned long __init alloc_down(unsigned long size, unsigned long align,
903                                        int highmem)
904 {
905         unsigned long base, addr = 0;
906
907         prom_debug("alloc_down(%x, %x, %s)\n", size, align,
908                    highmem ? RELOC("(high)") : RELOC("(low)"));
909         if (RELOC(ram_top) == 0)
910                 prom_panic("alloc_down() called with mem not initialized\n");
911
912         if (highmem) {
913                 /* Carve out storage for the TCE table. */
914                 addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align);
915                 if (addr <= RELOC(alloc_bottom))
916                         return 0;
917                 /* Will we bump into the RMO ? If yes, check out that we
918                  * didn't overlap existing allocations there, if we did,
919                  * we are dead, we must be the first in town !
920                  */
921                 if (addr < RELOC(rmo_top)) {
922                         /* Good, we are first */
923                         if (RELOC(alloc_top) == RELOC(rmo_top))
924                                 RELOC(alloc_top) = RELOC(rmo_top) = addr;
925                         else
926                                 return 0;
927                 }
928                 RELOC(alloc_top_high) = addr;
929                 goto bail;
930         }
931
932         base = _ALIGN_DOWN(RELOC(alloc_top) - size, align);
933         for (; base > RELOC(alloc_bottom);
934              base = _ALIGN_DOWN(base - 0x100000, align))  {
935                 prom_debug("    trying: 0x%x\n\r", base);
936                 addr = (unsigned long)prom_claim(base, size, 0);
937                 if (addr != PROM_ERROR && addr != 0)
938                         break;
939                 addr = 0;
940         }
941         if (addr == 0)
942                 return 0;
943         RELOC(alloc_top) = addr;
944
945  bail:
946         prom_debug(" -> %x\n", addr);
947         prom_debug("  alloc_bottom : %x\n", RELOC(alloc_bottom));
948         prom_debug("  alloc_top    : %x\n", RELOC(alloc_top));
949         prom_debug("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
950         prom_debug("  rmo_top      : %x\n", RELOC(rmo_top));
951         prom_debug("  ram_top      : %x\n", RELOC(ram_top));
952
953         return addr;
954 }
955
956 /*
957  * Parse a "reg" cell
958  */
959 static unsigned long __init prom_next_cell(int s, cell_t **cellp)
960 {
961         cell_t *p = *cellp;
962         unsigned long r = 0;
963
964         /* Ignore more than 2 cells */
965         while (s > sizeof(unsigned long) / 4) {
966                 p++;
967                 s--;
968         }
969         r = *p++;
970 #ifdef CONFIG_PPC64
971         if (s > 1) {
972                 r <<= 32;
973                 r |= *(p++);
974         }
975 #endif
976         *cellp = p;
977         return r;
978 }
979
980 /*
981  * Very dumb function for adding to the memory reserve list, but
982  * we don't need anything smarter at this point
983  *
984  * XXX Eventually check for collisions.  They should NEVER happen.
985  * If problems seem to show up, it would be a good start to track
986  * them down.
987  */
988 static void __init reserve_mem(u64 base, u64 size)
989 {
990         u64 top = base + size;
991         unsigned long cnt = RELOC(mem_reserve_cnt);
992
993         if (size == 0)
994                 return;
995
996         /* We need to always keep one empty entry so that we
997          * have our terminator with "size" set to 0 since we are
998          * dumb and just copy this entire array to the boot params
999          */
1000         base = _ALIGN_DOWN(base, PAGE_SIZE);
1001         top = _ALIGN_UP(top, PAGE_SIZE);
1002         size = top - base;
1003
1004         if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
1005                 prom_panic("Memory reserve map exhausted !\n");
1006         RELOC(mem_reserve_map)[cnt].base = base;
1007         RELOC(mem_reserve_map)[cnt].size = size;
1008         RELOC(mem_reserve_cnt) = cnt + 1;
1009 }
1010
1011 /*
1012  * Initialize memory allocation mechanism, parse "memory" nodes and
1013  * obtain that way the top of memory and RMO to setup out local allocator
1014  */
1015 static void __init prom_init_mem(void)
1016 {
1017         phandle node;
1018         char *path, type[64];
1019         unsigned int plen;
1020         cell_t *p, *endp;
1021         struct prom_t *_prom = &RELOC(prom);
1022         u32 rac, rsc;
1023
1024         /*
1025          * We iterate the memory nodes to find
1026          * 1) top of RMO (first node)
1027          * 2) top of memory
1028          */
1029         rac = 2;
1030         prom_getprop(_prom->root, "#address-cells", &rac, sizeof(rac));
1031         rsc = 1;
1032         prom_getprop(_prom->root, "#size-cells", &rsc, sizeof(rsc));
1033         prom_debug("root_addr_cells: %x\n", (unsigned long) rac);
1034         prom_debug("root_size_cells: %x\n", (unsigned long) rsc);
1035
1036         prom_debug("scanning memory:\n");
1037         path = RELOC(prom_scratch);
1038
1039         for (node = 0; prom_next_node(&node); ) {
1040                 type[0] = 0;
1041                 prom_getprop(node, "device_type", type, sizeof(type));
1042
1043                 if (type[0] == 0) {
1044                         /*
1045                          * CHRP Longtrail machines have no device_type
1046                          * on the memory node, so check the name instead...
1047                          */
1048                         prom_getprop(node, "name", type, sizeof(type));
1049                 }
1050                 if (strcmp(type, RELOC("memory")))
1051                         continue;
1052
1053                 plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf));
1054                 if (plen > sizeof(regbuf)) {
1055                         prom_printf("memory node too large for buffer !\n");
1056                         plen = sizeof(regbuf);
1057                 }
1058                 p = RELOC(regbuf);
1059                 endp = p + (plen / sizeof(cell_t));
1060
1061 #ifdef DEBUG_PROM
1062                 memset(path, 0, PROM_SCRATCH_SIZE);
1063                 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1064                 prom_debug("  node %s :\n", path);
1065 #endif /* DEBUG_PROM */
1066
1067                 while ((endp - p) >= (rac + rsc)) {
1068                         unsigned long base, size;
1069
1070                         base = prom_next_cell(rac, &p);
1071                         size = prom_next_cell(rsc, &p);
1072
1073                         if (size == 0)
1074                                 continue;
1075                         prom_debug("    %x %x\n", base, size);
1076                         if (base == 0 && (RELOC(of_platform) & PLATFORM_LPAR))
1077                                 RELOC(rmo_top) = size;
1078                         if ((base + size) > RELOC(ram_top))
1079                                 RELOC(ram_top) = base + size;
1080                 }
1081         }
1082
1083         RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000);
1084
1085         /* Check if we have an initrd after the kernel, if we do move our bottom
1086          * point to after it
1087          */
1088         if (RELOC(prom_initrd_start)) {
1089                 if (RELOC(prom_initrd_end) > RELOC(alloc_bottom))
1090                         RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
1091         }
1092
1093         /*
1094          * Setup our top alloc point, that is top of RMO or top of
1095          * segment 0 when running non-LPAR.
1096          * Some RS64 machines have buggy firmware where claims up at
1097          * 1GB fail.  Cap at 768MB as a workaround.
1098          * Since 768MB is plenty of room, and we need to cap to something
1099          * reasonable on 32-bit, cap at 768MB on all machines.
1100          */
1101         if (!RELOC(rmo_top))
1102                 RELOC(rmo_top) = RELOC(ram_top);
1103         RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top));
1104         RELOC(alloc_top) = RELOC(rmo_top);
1105         RELOC(alloc_top_high) = RELOC(ram_top);
1106
1107         prom_printf("memory layout at init:\n");
1108         prom_printf("  alloc_bottom : %x\n", RELOC(alloc_bottom));
1109         prom_printf("  alloc_top    : %x\n", RELOC(alloc_top));
1110         prom_printf("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
1111         prom_printf("  rmo_top      : %x\n", RELOC(rmo_top));
1112         prom_printf("  ram_top      : %x\n", RELOC(ram_top));
1113 }
1114
1115
1116 /*
1117  * Allocate room for and instantiate RTAS
1118  */
1119 static void __init prom_instantiate_rtas(void)
1120 {
1121         phandle rtas_node;
1122         ihandle rtas_inst;
1123         u32 base, entry = 0;
1124         u32 size = 0;
1125
1126         prom_debug("prom_instantiate_rtas: start...\n");
1127
1128         rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1129         prom_debug("rtas_node: %x\n", rtas_node);
1130         if (!PHANDLE_VALID(rtas_node))
1131                 return;
1132
1133         prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
1134         if (size == 0)
1135                 return;
1136
1137         base = alloc_down(size, PAGE_SIZE, 0);
1138         if (base == 0) {
1139                 prom_printf("RTAS allocation failed !\n");
1140                 return;
1141         }
1142
1143         rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
1144         if (!IHANDLE_VALID(rtas_inst)) {
1145                 prom_printf("opening rtas package failed (%x)\n", rtas_inst);
1146                 return;
1147         }
1148
1149         prom_printf("instantiating rtas at 0x%x ...", base);
1150
1151         if (call_prom_ret("call-method", 3, 2, &entry,
1152                           ADDR("instantiate-rtas"),
1153                           rtas_inst, base) != 0
1154             || entry == 0) {
1155                 prom_printf(" failed\n");
1156                 return;
1157         }
1158         prom_printf(" done\n");
1159
1160         reserve_mem(base, size);
1161
1162         prom_setprop(rtas_node, "/rtas", "linux,rtas-base",
1163                      &base, sizeof(base));
1164         prom_setprop(rtas_node, "/rtas", "linux,rtas-entry",
1165                      &entry, sizeof(entry));
1166
1167         prom_debug("rtas base     = 0x%x\n", base);
1168         prom_debug("rtas entry    = 0x%x\n", entry);
1169         prom_debug("rtas size     = 0x%x\n", (long)size);
1170
1171         prom_debug("prom_instantiate_rtas: end...\n");
1172 }
1173
1174 #ifdef CONFIG_PPC64
1175 /*
1176  * Allocate room for and initialize TCE tables
1177  */
1178 static void __init prom_initialize_tce_table(void)
1179 {
1180         phandle node;
1181         ihandle phb_node;
1182         char compatible[64], type[64], model[64];
1183         char *path = RELOC(prom_scratch);
1184         u64 base, align;
1185         u32 minalign, minsize;
1186         u64 tce_entry, *tce_entryp;
1187         u64 local_alloc_top, local_alloc_bottom;
1188         u64 i;
1189
1190         if (RELOC(prom_iommu_off))
1191                 return;
1192
1193         prom_debug("starting prom_initialize_tce_table\n");
1194
1195         /* Cache current top of allocs so we reserve a single block */
1196         local_alloc_top = RELOC(alloc_top_high);
1197         local_alloc_bottom = local_alloc_top;
1198
1199         /* Search all nodes looking for PHBs. */
1200         for (node = 0; prom_next_node(&node); ) {
1201                 compatible[0] = 0;
1202                 type[0] = 0;
1203                 model[0] = 0;
1204                 prom_getprop(node, "compatible",
1205                              compatible, sizeof(compatible));
1206                 prom_getprop(node, "device_type", type, sizeof(type));
1207                 prom_getprop(node, "model", model, sizeof(model));
1208
1209                 if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL))
1210                         continue;
1211
1212                 /* Keep the old logic intact to avoid regression. */
1213                 if (compatible[0] != 0) {
1214                         if ((strstr(compatible, RELOC("python")) == NULL) &&
1215                             (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
1216                             (strstr(compatible, RELOC("Winnipeg")) == NULL))
1217                                 continue;
1218                 } else if (model[0] != 0) {
1219                         if ((strstr(model, RELOC("ython")) == NULL) &&
1220                             (strstr(model, RELOC("peedwagon")) == NULL) &&
1221                             (strstr(model, RELOC("innipeg")) == NULL))
1222                                 continue;
1223                 }
1224
1225                 if (prom_getprop(node, "tce-table-minalign", &minalign,
1226                                  sizeof(minalign)) == PROM_ERROR)
1227                         minalign = 0;
1228                 if (prom_getprop(node, "tce-table-minsize", &minsize,
1229                                  sizeof(minsize)) == PROM_ERROR)
1230                         minsize = 4UL << 20;
1231
1232                 /*
1233                  * Even though we read what OF wants, we just set the table
1234                  * size to 4 MB.  This is enough to map 2GB of PCI DMA space.
1235                  * By doing this, we avoid the pitfalls of trying to DMA to
1236                  * MMIO space and the DMA alias hole.
1237                  *
1238                  * On POWER4, firmware sets the TCE region by assuming
1239                  * each TCE table is 8MB. Using this memory for anything
1240                  * else will impact performance, so we always allocate 8MB.
1241                  * Anton
1242                  */
1243                 if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
1244                         minsize = 8UL << 20;
1245                 else
1246                         minsize = 4UL << 20;
1247
1248                 /* Align to the greater of the align or size */
1249                 align = max(minalign, minsize);
1250                 base = alloc_down(minsize, align, 1);
1251                 if (base == 0)
1252                         prom_panic("ERROR, cannot find space for TCE table.\n");
1253                 if (base < local_alloc_bottom)
1254                         local_alloc_bottom = base;
1255
1256                 /* It seems OF doesn't null-terminate the path :-( */
1257                 memset(path, 0, PROM_SCRATCH_SIZE);
1258                 /* Call OF to setup the TCE hardware */
1259                 if (call_prom("package-to-path", 3, 1, node,
1260                               path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
1261                         prom_printf("package-to-path failed\n");
1262                 }
1263
1264                 /* Save away the TCE table attributes for later use. */
1265                 prom_setprop(node, path, "linux,tce-base", &base, sizeof(base));
1266                 prom_setprop(node, path, "linux,tce-size", &minsize, sizeof(minsize));
1267
1268                 prom_debug("TCE table: %s\n", path);
1269                 prom_debug("\tnode = 0x%x\n", node);
1270                 prom_debug("\tbase = 0x%x\n", base);
1271                 prom_debug("\tsize = 0x%x\n", minsize);
1272
1273                 /* Initialize the table to have a one-to-one mapping
1274                  * over the allocated size.
1275                  */
1276                 tce_entryp = (unsigned long *)base;
1277                 for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
1278                         tce_entry = (i << PAGE_SHIFT);
1279                         tce_entry |= 0x3;
1280                         *tce_entryp = tce_entry;
1281                 }
1282
1283                 prom_printf("opening PHB %s", path);
1284                 phb_node = call_prom("open", 1, 1, path);
1285                 if (phb_node == 0)
1286                         prom_printf("... failed\n");
1287                 else
1288                         prom_printf("... done\n");
1289
1290                 call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
1291                           phb_node, -1, minsize,
1292                           (u32) base, (u32) (base >> 32));
1293                 call_prom("close", 1, 0, phb_node);
1294         }
1295
1296         reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
1297
1298         /* These are only really needed if there is a memory limit in
1299          * effect, but we don't know so export them always. */
1300         RELOC(prom_tce_alloc_start) = local_alloc_bottom;
1301         RELOC(prom_tce_alloc_end) = local_alloc_top;
1302
1303         /* Flag the first invalid entry */
1304         prom_debug("ending prom_initialize_tce_table\n");
1305 }
1306 #endif
1307
1308 /*
1309  * With CHRP SMP we need to use the OF to start the other processors.
1310  * We can't wait until smp_boot_cpus (the OF is trashed by then)
1311  * so we have to put the processors into a holding pattern controlled
1312  * by the kernel (not OF) before we destroy the OF.
1313  *
1314  * This uses a chunk of low memory, puts some holding pattern
1315  * code there and sends the other processors off to there until
1316  * smp_boot_cpus tells them to do something.  The holding pattern
1317  * checks that address until its cpu # is there, when it is that
1318  * cpu jumps to __secondary_start().  smp_boot_cpus() takes care
1319  * of setting those values.
1320  *
1321  * We also use physical address 0x4 here to tell when a cpu
1322  * is in its holding pattern code.
1323  *
1324  * -- Cort
1325  */
1326 extern void __secondary_hold(void);
1327 extern unsigned long __secondary_hold_spinloop;
1328 extern unsigned long __secondary_hold_acknowledge;
1329
1330 /*
1331  * We want to reference the copy of __secondary_hold_* in the
1332  * 0 - 0x100 address range
1333  */
1334 #define LOW_ADDR(x)     (((unsigned long) &(x)) & 0xff)
1335
1336 static void __init prom_hold_cpus(void)
1337 {
1338         unsigned long i;
1339         unsigned int reg;
1340         phandle node;
1341         char type[64];
1342         int cpuid = 0;
1343         unsigned int interrupt_server[MAX_CPU_THREADS];
1344         unsigned int cpu_threads, hw_cpu_num;
1345         int propsize;
1346         struct prom_t *_prom = &RELOC(prom);
1347         unsigned long *spinloop
1348                 = (void *) LOW_ADDR(__secondary_hold_spinloop);
1349         unsigned long *acknowledge
1350                 = (void *) LOW_ADDR(__secondary_hold_acknowledge);
1351 #ifdef CONFIG_PPC64
1352         /* __secondary_hold is actually a descriptor, not the text address */
1353         unsigned long secondary_hold
1354                 = __pa(*PTRRELOC((unsigned long *)__secondary_hold));
1355 #else
1356         unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
1357 #endif
1358
1359         prom_debug("prom_hold_cpus: start...\n");
1360         prom_debug("    1) spinloop       = 0x%x\n", (unsigned long)spinloop);
1361         prom_debug("    1) *spinloop      = 0x%x\n", *spinloop);
1362         prom_debug("    1) acknowledge    = 0x%x\n",
1363                    (unsigned long)acknowledge);
1364         prom_debug("    1) *acknowledge   = 0x%x\n", *acknowledge);
1365         prom_debug("    1) secondary_hold = 0x%x\n", secondary_hold);
1366
1367         /* Set the common spinloop variable, so all of the secondary cpus
1368          * will block when they are awakened from their OF spinloop.
1369          * This must occur for both SMP and non SMP kernels, since OF will
1370          * be trashed when we move the kernel.
1371          */
1372         *spinloop = 0;
1373
1374         /* look for cpus */
1375         for (node = 0; prom_next_node(&node); ) {
1376                 type[0] = 0;
1377                 prom_getprop(node, "device_type", type, sizeof(type));
1378                 if (strcmp(type, RELOC("cpu")) != 0)
1379                         continue;
1380
1381                 /* Skip non-configured cpus. */
1382                 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1383                         if (strcmp(type, RELOC("okay")) != 0)
1384                                 continue;
1385
1386                 reg = -1;
1387                 prom_getprop(node, "reg", &reg, sizeof(reg));
1388
1389                 prom_debug("\ncpuid        = 0x%x\n", cpuid);
1390                 prom_debug("cpu hw idx   = 0x%x\n", reg);
1391
1392                 /* Init the acknowledge var which will be reset by
1393                  * the secondary cpu when it awakens from its OF
1394                  * spinloop.
1395                  */
1396                 *acknowledge = (unsigned long)-1;
1397
1398                 propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s",
1399                                         &interrupt_server,
1400                                         sizeof(interrupt_server));
1401                 if (propsize < 0) {
1402                         /* no property.  old hardware has no SMT */
1403                         cpu_threads = 1;
1404                         interrupt_server[0] = reg; /* fake it with phys id */
1405                 } else {
1406                         /* We have a threaded processor */
1407                         cpu_threads = propsize / sizeof(u32);
1408                         if (cpu_threads > MAX_CPU_THREADS) {
1409                                 prom_printf("SMT: too many threads!\n"
1410                                             "SMT: found %x, max is %x\n",
1411                                             cpu_threads, MAX_CPU_THREADS);
1412                                 cpu_threads = 1; /* ToDo: panic? */
1413                         }
1414                 }
1415
1416                 hw_cpu_num = interrupt_server[0];
1417                 if (hw_cpu_num != _prom->cpu) {
1418                         /* Primary Thread of non-boot cpu */
1419                         prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg);
1420                         call_prom("start-cpu", 3, 0, node,
1421                                   secondary_hold, reg);
1422
1423                         for (i = 0; (i < 100000000) && 
1424                              (*acknowledge == ((unsigned long)-1)); i++ )
1425                                 mb();
1426
1427                         if (*acknowledge == reg)
1428                                 prom_printf("done\n");
1429                         else
1430                                 prom_printf("failed: %x\n", *acknowledge);
1431                 }
1432 #ifdef CONFIG_SMP
1433                 else
1434                         prom_printf("%x : boot cpu     %x\n", cpuid, reg);
1435 #endif /* CONFIG_SMP */
1436
1437                 /* Reserve cpu #s for secondary threads.   They start later. */
1438                 cpuid += cpu_threads;
1439         }
1440
1441         if (cpuid > NR_CPUS)
1442                 prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS)
1443                             ") exceeded: ignoring extras\n");
1444
1445         prom_debug("prom_hold_cpus: end...\n");
1446 }
1447
1448
1449 static void __init prom_init_client_services(unsigned long pp)
1450 {
1451         struct prom_t *_prom = &RELOC(prom);
1452
1453         /* Get a handle to the prom entry point before anything else */
1454         RELOC(prom_entry) = pp;
1455
1456         /* get a handle for the stdout device */
1457         _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
1458         if (!PHANDLE_VALID(_prom->chosen))
1459                 prom_panic("cannot find chosen"); /* msg won't be printed :( */
1460
1461         /* get device tree root */
1462         _prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
1463         if (!PHANDLE_VALID(_prom->root))
1464                 prom_panic("cannot find device tree root"); /* msg won't be printed :( */
1465
1466         _prom->mmumap = 0;
1467 }
1468
1469 #ifdef CONFIG_PPC32
1470 /*
1471  * For really old powermacs, we need to map things we claim.
1472  * For that, we need the ihandle of the mmu.
1473  * Also, on the longtrail, we need to work around other bugs.
1474  */
1475 static void __init prom_find_mmu(void)
1476 {
1477         struct prom_t *_prom = &RELOC(prom);
1478         phandle oprom;
1479         char version[64];
1480
1481         oprom = call_prom("finddevice", 1, 1, ADDR("/openprom"));
1482         if (!PHANDLE_VALID(oprom))
1483                 return;
1484         if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
1485                 return;
1486         version[sizeof(version) - 1] = 0;
1487         /* XXX might need to add other versions here */
1488         if (strcmp(version, "Open Firmware, 1.0.5") == 0)
1489                 of_workarounds = OF_WA_CLAIM;
1490         else if (strncmp(version, "FirmWorks,3.", 12) == 0) {
1491                 of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;
1492                 call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");
1493         } else
1494                 return;
1495         _prom->memory = call_prom("open", 1, 1, ADDR("/memory"));
1496         prom_getprop(_prom->chosen, "mmu", &_prom->mmumap,
1497                      sizeof(_prom->mmumap));
1498         if (!IHANDLE_VALID(_prom->memory) || !IHANDLE_VALID(_prom->mmumap))
1499                 of_workarounds &= ~OF_WA_CLAIM;         /* hmmm */
1500 }
1501 #else
1502 #define prom_find_mmu()
1503 #endif
1504
1505 static void __init prom_init_stdout(void)
1506 {
1507         struct prom_t *_prom = &RELOC(prom);
1508         char *path = RELOC(of_stdout_device);
1509         char type[16];
1510         u32 val;
1511
1512         if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)
1513                 prom_panic("cannot find stdout");
1514
1515         _prom->stdout = val;
1516
1517         /* Get the full OF pathname of the stdout device */
1518         memset(path, 0, 256);
1519         call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
1520         val = call_prom("instance-to-package", 1, 1, _prom->stdout);
1521         prom_setprop(_prom->chosen, "/chosen", "linux,stdout-package",
1522                      &val, sizeof(val));
1523         prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
1524         prom_setprop(_prom->chosen, "/chosen", "linux,stdout-path",
1525                      path, strlen(path) + 1);
1526
1527         /* If it's a display, note it */
1528         memset(type, 0, sizeof(type));
1529         prom_getprop(val, "device_type", type, sizeof(type));
1530         if (strcmp(type, RELOC("display")) == 0)
1531                 prom_setprop(val, path, "linux,boot-display", NULL, 0);
1532 }
1533
1534 static void __init prom_close_stdin(void)
1535 {
1536         struct prom_t *_prom = &RELOC(prom);
1537         ihandle val;
1538
1539         if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
1540                 call_prom("close", 1, 0, val);
1541 }
1542
1543 static int __init prom_find_machine_type(void)
1544 {
1545         struct prom_t *_prom = &RELOC(prom);
1546         char compat[256];
1547         int len, i = 0;
1548 #ifdef CONFIG_PPC64
1549         phandle rtas;
1550         int x;
1551 #endif
1552
1553         /* Look for a PowerMac */
1554         len = prom_getprop(_prom->root, "compatible",
1555                            compat, sizeof(compat)-1);
1556         if (len > 0) {
1557                 compat[len] = 0;
1558                 while (i < len) {
1559                         char *p = &compat[i];
1560                         int sl = strlen(p);
1561                         if (sl == 0)
1562                                 break;
1563                         if (strstr(p, RELOC("Power Macintosh")) ||
1564                             strstr(p, RELOC("MacRISC")))
1565                                 return PLATFORM_POWERMAC;
1566 #ifdef CONFIG_PPC64
1567                         /* We must make sure we don't detect the IBM Cell
1568                          * blades as pSeries due to some firmware issues,
1569                          * so we do it here.
1570                          */
1571                         if (strstr(p, RELOC("IBM,CBEA")) ||
1572                             strstr(p, RELOC("IBM,CPBW-1.0")))
1573                                 return PLATFORM_GENERIC;
1574 #endif /* CONFIG_PPC64 */
1575                         i += sl + 1;
1576                 }
1577         }
1578 #ifdef CONFIG_PPC64
1579         /* If not a mac, try to figure out if it's an IBM pSeries or any other
1580          * PAPR compliant platform. We assume it is if :
1581          *  - /device_type is "chrp" (please, do NOT use that for future
1582          *    non-IBM designs !
1583          *  - it has /rtas
1584          */
1585         len = prom_getprop(_prom->root, "device_type",
1586                            compat, sizeof(compat)-1);
1587         if (len <= 0)
1588                 return PLATFORM_GENERIC;
1589         if (strcmp(compat, RELOC("chrp")))
1590                 return PLATFORM_GENERIC;
1591
1592         /* Default to pSeries. We need to know if we are running LPAR */
1593         rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1594         if (!PHANDLE_VALID(rtas))
1595                 return PLATFORM_GENERIC;
1596         x = prom_getproplen(rtas, "ibm,hypertas-functions");
1597         if (x != PROM_ERROR) {
1598                 prom_printf("Hypertas detected, assuming LPAR !\n");
1599                 return PLATFORM_PSERIES_LPAR;
1600         }
1601         return PLATFORM_PSERIES;
1602 #else
1603         return PLATFORM_GENERIC;
1604 #endif
1605 }
1606
1607 static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
1608 {
1609         return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
1610 }
1611
1612 /*
1613  * If we have a display that we don't know how to drive,
1614  * we will want to try to execute OF's open method for it
1615  * later.  However, OF will probably fall over if we do that
1616  * we've taken over the MMU.
1617  * So we check whether we will need to open the display,
1618  * and if so, open it now.
1619  */
1620 static void __init prom_check_displays(void)
1621 {
1622         char type[16], *path;
1623         phandle node;
1624         ihandle ih;
1625         int i;
1626
1627         static unsigned char default_colors[] = {
1628                 0x00, 0x00, 0x00,
1629                 0x00, 0x00, 0xaa,
1630                 0x00, 0xaa, 0x00,
1631                 0x00, 0xaa, 0xaa,
1632                 0xaa, 0x00, 0x00,
1633                 0xaa, 0x00, 0xaa,
1634                 0xaa, 0xaa, 0x00,
1635                 0xaa, 0xaa, 0xaa,
1636                 0x55, 0x55, 0x55,
1637                 0x55, 0x55, 0xff,
1638                 0x55, 0xff, 0x55,
1639                 0x55, 0xff, 0xff,
1640                 0xff, 0x55, 0x55,
1641                 0xff, 0x55, 0xff,
1642                 0xff, 0xff, 0x55,
1643                 0xff, 0xff, 0xff
1644         };
1645         const unsigned char *clut;
1646
1647         prom_printf("Looking for displays\n");
1648         for (node = 0; prom_next_node(&node); ) {
1649                 memset(type, 0, sizeof(type));
1650                 prom_getprop(node, "device_type", type, sizeof(type));
1651                 if (strcmp(type, RELOC("display")) != 0)
1652                         continue;
1653
1654                 /* It seems OF doesn't null-terminate the path :-( */
1655                 path = RELOC(prom_scratch);
1656                 memset(path, 0, PROM_SCRATCH_SIZE);
1657
1658                 /*
1659                  * leave some room at the end of the path for appending extra
1660                  * arguments
1661                  */
1662                 if (call_prom("package-to-path", 3, 1, node, path,
1663                               PROM_SCRATCH_SIZE-10) == PROM_ERROR)
1664                         continue;
1665                 prom_printf("found display   : %s, opening ... ", path);
1666                 
1667                 ih = call_prom("open", 1, 1, path);
1668                 if (ih == 0) {
1669                         prom_printf("failed\n");
1670                         continue;
1671                 }
1672
1673                 /* Success */
1674                 prom_printf("done\n");
1675                 prom_setprop(node, path, "linux,opened", NULL, 0);
1676
1677                 /* Setup a usable color table when the appropriate
1678                  * method is available. Should update this to set-colors */
1679                 clut = RELOC(default_colors);
1680                 for (i = 0; i < 32; i++, clut += 3)
1681                         if (prom_set_color(ih, i, clut[0], clut[1],
1682                                            clut[2]) != 0)
1683                                 break;
1684
1685 #ifdef CONFIG_LOGO_LINUX_CLUT224
1686                 clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
1687                 for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
1688                         if (prom_set_color(ih, i + 32, clut[0], clut[1],
1689                                            clut[2]) != 0)
1690                                 break;
1691 #endif /* CONFIG_LOGO_LINUX_CLUT224 */
1692         }
1693 }
1694
1695
1696 /* Return (relocated) pointer to this much memory: moves initrd if reqd. */
1697 static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
1698                               unsigned long needed, unsigned long align)
1699 {
1700         void *ret;
1701
1702         *mem_start = _ALIGN(*mem_start, align);
1703         while ((*mem_start + needed) > *mem_end) {
1704                 unsigned long room, chunk;
1705
1706                 prom_debug("Chunk exhausted, claiming more at %x...\n",
1707                            RELOC(alloc_bottom));
1708                 room = RELOC(alloc_top) - RELOC(alloc_bottom);
1709                 if (room > DEVTREE_CHUNK_SIZE)
1710                         room = DEVTREE_CHUNK_SIZE;
1711                 if (room < PAGE_SIZE)
1712                         prom_panic("No memory for flatten_device_tree (no room)");
1713                 chunk = alloc_up(room, 0);
1714                 if (chunk == 0)
1715                         prom_panic("No memory for flatten_device_tree (claim failed)");
1716                 *mem_end = RELOC(alloc_top);
1717         }
1718
1719         ret = (void *)*mem_start;
1720         *mem_start += needed;
1721
1722         return ret;
1723 }
1724
1725 #define dt_push_token(token, mem_start, mem_end) \
1726         do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)
1727
1728 static unsigned long __init dt_find_string(char *str)
1729 {
1730         char *s, *os;
1731
1732         s = os = (char *)RELOC(dt_string_start);
1733         s += 4;
1734         while (s <  (char *)RELOC(dt_string_end)) {
1735                 if (strcmp(s, str) == 0)
1736                         return s - os;
1737                 s += strlen(s) + 1;
1738         }
1739         return 0;
1740 }
1741
1742 /*
1743  * The Open Firmware 1275 specification states properties must be 31 bytes or
1744  * less, however not all firmwares obey this. Make it 64 bytes to be safe.
1745  */
1746 #define MAX_PROPERTY_NAME 64
1747
1748 static void __init scan_dt_build_strings(phandle node,
1749                                          unsigned long *mem_start,
1750                                          unsigned long *mem_end)
1751 {
1752         char *prev_name, *namep, *sstart;
1753         unsigned long soff;
1754         phandle child;
1755
1756         sstart =  (char *)RELOC(dt_string_start);
1757
1758         /* get and store all property names */
1759         prev_name = RELOC("");
1760         for (;;) {
1761                 /* 64 is max len of name including nul. */
1762                 namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
1763                 if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
1764                         /* No more nodes: unwind alloc */
1765                         *mem_start = (unsigned long)namep;
1766                         break;
1767                 }
1768
1769                 /* skip "name" */
1770                 if (strcmp(namep, RELOC("name")) == 0) {
1771                         *mem_start = (unsigned long)namep;
1772                         prev_name = RELOC("name");
1773                         continue;
1774                 }
1775                 /* get/create string entry */
1776                 soff = dt_find_string(namep);
1777                 if (soff != 0) {
1778                         *mem_start = (unsigned long)namep;
1779                         namep = sstart + soff;
1780                 } else {
1781                         /* Trim off some if we can */
1782                         *mem_start = (unsigned long)namep + strlen(namep) + 1;
1783                         RELOC(dt_string_end) = *mem_start;
1784                 }
1785                 prev_name = namep;
1786         }
1787
1788         /* do all our children */
1789         child = call_prom("child", 1, 1, node);
1790         while (child != 0) {
1791                 scan_dt_build_strings(child, mem_start, mem_end);
1792                 child = call_prom("peer", 1, 1, child);
1793         }
1794 }
1795
1796 static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1797                                         unsigned long *mem_end)
1798 {
1799         phandle child;
1800         char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
1801         unsigned long soff;
1802         unsigned char *valp;
1803         static char pname[MAX_PROPERTY_NAME];
1804         int l, room;
1805
1806         dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
1807
1808         /* get the node's full name */
1809         namep = (char *)*mem_start;
1810         room = *mem_end - *mem_start;
1811         if (room > 255)
1812                 room = 255;
1813         l = call_prom("package-to-path", 3, 1, node, namep, room);
1814         if (l >= 0) {
1815                 /* Didn't fit?  Get more room. */
1816                 if (l >= room) {
1817                         if (l >= *mem_end - *mem_start)
1818                                 namep = make_room(mem_start, mem_end, l+1, 1);
1819                         call_prom("package-to-path", 3, 1, node, namep, l);
1820                 }
1821                 namep[l] = '\0';
1822
1823                 /* Fixup an Apple bug where they have bogus \0 chars in the
1824                  * middle of the path in some properties, and extract
1825                  * the unit name (everything after the last '/').
1826                  */
1827                 for (lp = p = namep, ep = namep + l; p < ep; p++) {
1828                         if (*p == '/')
1829                                 lp = namep;
1830                         else if (*p != 0)
1831                                 *lp++ = *p;
1832                 }
1833                 *lp = 0;
1834                 *mem_start = _ALIGN((unsigned long)lp + 1, 4);
1835         }
1836
1837         /* get it again for debugging */
1838         path = RELOC(prom_scratch);
1839         memset(path, 0, PROM_SCRATCH_SIZE);
1840         call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1841
1842         /* get and store all properties */
1843         prev_name = RELOC("");
1844         sstart = (char *)RELOC(dt_string_start);
1845         for (;;) {
1846                 if (call_prom("nextprop", 3, 1, node, prev_name,
1847                               RELOC(pname)) != 1)
1848                         break;
1849
1850                 /* skip "name" */
1851                 if (strcmp(RELOC(pname), RELOC("name")) == 0) {
1852                         prev_name = RELOC("name");
1853                         continue;
1854                 }
1855
1856                 /* find string offset */
1857                 soff = dt_find_string(RELOC(pname));
1858                 if (soff == 0) {
1859                         prom_printf("WARNING: Can't find string index for"
1860                                     " <%s>, node %s\n", RELOC(pname), path);
1861                         break;
1862                 }
1863                 prev_name = sstart + soff;
1864
1865                 /* get length */
1866                 l = call_prom("getproplen", 2, 1, node, RELOC(pname));
1867
1868                 /* sanity checks */
1869                 if (l == PROM_ERROR)
1870                         continue;
1871                 if (l > MAX_PROPERTY_LENGTH) {
1872                         prom_printf("WARNING: ignoring large property ");
1873                         /* It seems OF doesn't null-terminate the path :-( */
1874                         prom_printf("[%s] ", path);
1875                         prom_printf("%s length 0x%x\n", RELOC(pname), l);
1876                         continue;
1877                 }
1878
1879                 /* push property head */
1880                 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1881                 dt_push_token(l, mem_start, mem_end);
1882                 dt_push_token(soff, mem_start, mem_end);
1883
1884                 /* push property content */
1885                 valp = make_room(mem_start, mem_end, l, 4);
1886                 call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
1887                 *mem_start = _ALIGN(*mem_start, 4);
1888         }
1889
1890         /* Add a "linux,phandle" property. */
1891         soff = dt_find_string(RELOC("linux,phandle"));
1892         if (soff == 0)
1893                 prom_printf("WARNING: Can't find string index for"
1894                             " <linux-phandle> node %s\n", path);
1895         else {
1896                 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1897                 dt_push_token(4, mem_start, mem_end);
1898                 dt_push_token(soff, mem_start, mem_end);
1899                 valp = make_room(mem_start, mem_end, 4, 4);
1900                 *(u32 *)valp = node;
1901         }
1902
1903         /* do all our children */
1904         child = call_prom("child", 1, 1, node);
1905         while (child != 0) {
1906                 scan_dt_build_struct(child, mem_start, mem_end);
1907                 child = call_prom("peer", 1, 1, child);
1908         }
1909
1910         dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
1911 }
1912
1913 static void __init flatten_device_tree(void)
1914 {
1915         phandle root;
1916         unsigned long mem_start, mem_end, room;
1917         struct boot_param_header *hdr;
1918         struct prom_t *_prom = &RELOC(prom);
1919         char *namep;
1920         u64 *rsvmap;
1921
1922         /*
1923          * Check how much room we have between alloc top & bottom (+/- a
1924          * few pages), crop to 4Mb, as this is our "chuck" size
1925          */
1926         room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000;
1927         if (room > DEVTREE_CHUNK_SIZE)
1928                 room = DEVTREE_CHUNK_SIZE;
1929         prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom));
1930
1931         /* Now try to claim that */
1932         mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
1933         if (mem_start == 0)
1934                 prom_panic("Can't allocate initial device-tree chunk\n");
1935         mem_end = RELOC(alloc_top);
1936
1937         /* Get root of tree */
1938         root = call_prom("peer", 1, 1, (phandle)0);
1939         if (root == (phandle)0)
1940                 prom_panic ("couldn't get device tree root\n");
1941
1942         /* Build header and make room for mem rsv map */ 
1943         mem_start = _ALIGN(mem_start, 4);
1944         hdr = make_room(&mem_start, &mem_end,
1945                         sizeof(struct boot_param_header), 4);
1946         RELOC(dt_header_start) = (unsigned long)hdr;
1947         rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
1948
1949         /* Start of strings */
1950         mem_start = PAGE_ALIGN(mem_start);
1951         RELOC(dt_string_start) = mem_start;
1952         mem_start += 4; /* hole */
1953
1954         /* Add "linux,phandle" in there, we'll need it */
1955         namep = make_room(&mem_start, &mem_end, 16, 1);
1956         strcpy(namep, RELOC("linux,phandle"));
1957         mem_start = (unsigned long)namep + strlen(namep) + 1;
1958
1959         /* Build string array */
1960         prom_printf("Building dt strings...\n"); 
1961         scan_dt_build_strings(root, &mem_start, &mem_end);
1962         RELOC(dt_string_end) = mem_start;
1963
1964         /* Build structure */
1965         mem_start = PAGE_ALIGN(mem_start);
1966         RELOC(dt_struct_start) = mem_start;
1967         prom_printf("Building dt structure...\n"); 
1968         scan_dt_build_struct(root, &mem_start, &mem_end);
1969         dt_push_token(OF_DT_END, &mem_start, &mem_end);
1970         RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
1971
1972         /* Finish header */
1973         hdr->boot_cpuid_phys = _prom->cpu;
1974         hdr->magic = OF_DT_HEADER;
1975         hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
1976         hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
1977         hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start);
1978         hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start);
1979         hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start);
1980         hdr->version = OF_DT_VERSION;
1981         /* Version 16 is not backward compatible */
1982         hdr->last_comp_version = 0x10;
1983
1984         /* Copy the reserve map in */
1985         memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
1986
1987 #ifdef DEBUG_PROM
1988         {
1989                 int i;
1990                 prom_printf("reserved memory map:\n");
1991                 for (i = 0; i < RELOC(mem_reserve_cnt); i++)
1992                         prom_printf("  %x - %x\n",
1993                                     RELOC(mem_reserve_map)[i].base,
1994                                     RELOC(mem_reserve_map)[i].size);
1995         }
1996 #endif
1997         /* Bump mem_reserve_cnt to cause further reservations to fail
1998          * since it's too late.
1999          */
2000         RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
2001
2002         prom_printf("Device tree strings 0x%x -> 0x%x\n",
2003                     RELOC(dt_string_start), RELOC(dt_string_end)); 
2004         prom_printf("Device tree struct  0x%x -> 0x%x\n",
2005                     RELOC(dt_struct_start), RELOC(dt_struct_end));
2006
2007 }
2008
2009 #ifdef CONFIG_PPC_MAPLE
2010 /* PIBS Version 1.05.0000 04/26/2005 has an incorrect /ht/isa/ranges property.
2011  * The values are bad, and it doesn't even have the right number of cells. */
2012 static void __init fixup_device_tree_maple(void)
2013 {
2014         phandle isa;
2015         u32 rloc = 0x01002000; /* IO space; PCI device = 4 */
2016         u32 isa_ranges[6];
2017         char *name;
2018
2019         name = "/ht@0/isa@4";
2020         isa = call_prom("finddevice", 1, 1, ADDR(name));
2021         if (!PHANDLE_VALID(isa)) {
2022                 name = "/ht@0/isa@6";
2023                 isa = call_prom("finddevice", 1, 1, ADDR(name));
2024                 rloc = 0x01003000; /* IO space; PCI device = 6 */
2025         }
2026         if (!PHANDLE_VALID(isa))
2027                 return;
2028
2029         if (prom_getproplen(isa, "ranges") != 12)
2030                 return;
2031         if (prom_getprop(isa, "ranges", isa_ranges, sizeof(isa_ranges))
2032                 == PROM_ERROR)
2033                 return;
2034
2035         if (isa_ranges[0] != 0x1 ||
2036                 isa_ranges[1] != 0xf4000000 ||
2037                 isa_ranges[2] != 0x00010000)
2038                 return;
2039
2040         prom_printf("Fixing up bogus ISA range on Maple/Apache...\n");
2041
2042         isa_ranges[0] = 0x1;
2043         isa_ranges[1] = 0x0;
2044         isa_ranges[2] = rloc;
2045         isa_ranges[3] = 0x0;
2046         isa_ranges[4] = 0x0;
2047         isa_ranges[5] = 0x00010000;
2048         prom_setprop(isa, name, "ranges",
2049                         isa_ranges, sizeof(isa_ranges));
2050 }
2051 #else
2052 #define fixup_device_tree_maple()
2053 #endif
2054
2055 #ifdef CONFIG_PPC_CHRP
2056 /*
2057  * Pegasos and BriQ lacks the "ranges" property in the isa node
2058  * Pegasos needs decimal IRQ 14/15, not hexadecimal
2059  * Pegasos has the IDE configured in legacy mode, but advertised as native
2060  */
2061 static void __init fixup_device_tree_chrp(void)
2062 {
2063         phandle ph;
2064         u32 prop[6];
2065         u32 rloc = 0x01006000; /* IO space; PCI device = 12 */
2066         char *name;
2067         int rc;
2068
2069         name = "/pci@80000000/isa@c";
2070         ph = call_prom("finddevice", 1, 1, ADDR(name));
2071         if (!PHANDLE_VALID(ph)) {
2072                 name = "/pci@ff500000/isa@6";
2073                 ph = call_prom("finddevice", 1, 1, ADDR(name));
2074                 rloc = 0x01003000; /* IO space; PCI device = 6 */
2075         }
2076         if (PHANDLE_VALID(ph)) {
2077                 rc = prom_getproplen(ph, "ranges");
2078                 if (rc == 0 || rc == PROM_ERROR) {
2079                         prom_printf("Fixing up missing ISA range on Pegasos...\n");
2080
2081                         prop[0] = 0x1;
2082                         prop[1] = 0x0;
2083                         prop[2] = rloc;
2084                         prop[3] = 0x0;
2085                         prop[4] = 0x0;
2086                         prop[5] = 0x00010000;
2087                         prom_setprop(ph, name, "ranges", prop, sizeof(prop));
2088                 }
2089         }
2090
2091         name = "/pci@80000000/ide@C,1";
2092         ph = call_prom("finddevice", 1, 1, ADDR(name));
2093         if (PHANDLE_VALID(ph)) {
2094                 prom_printf("Fixing up IDE interrupt on Pegasos...\n");
2095                 prop[0] = 14;
2096                 prop[1] = 0x0;
2097                 prom_setprop(ph, name, "interrupts", prop, 2*sizeof(u32));
2098                 prom_printf("Fixing up IDE class-code on Pegasos...\n");
2099                 rc = prom_getprop(ph, "class-code", prop, sizeof(u32));
2100                 if (rc == sizeof(u32)) {
2101                         prop[0] &= ~0x5;
2102                         prom_setprop(ph, name, "class-code", prop, sizeof(u32));
2103                 }
2104         }
2105 }
2106 #else
2107 #define fixup_device_tree_chrp()
2108 #endif
2109
2110 #if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
2111 static void __init fixup_device_tree_pmac(void)
2112 {
2113         phandle u3, i2c, mpic;
2114         u32 u3_rev;
2115         u32 interrupts[2];
2116         u32 parent;
2117
2118         /* Some G5s have a missing interrupt definition, fix it up here */
2119         u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
2120         if (!PHANDLE_VALID(u3))
2121                 return;
2122         i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
2123         if (!PHANDLE_VALID(i2c))
2124                 return;
2125         mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
2126         if (!PHANDLE_VALID(mpic))
2127                 return;
2128
2129         /* check if proper rev of u3 */
2130         if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
2131             == PROM_ERROR)
2132                 return;
2133         if (u3_rev < 0x35 || u3_rev > 0x39)
2134                 return;
2135         /* does it need fixup ? */
2136         if (prom_getproplen(i2c, "interrupts") > 0)
2137                 return;
2138
2139         prom_printf("fixing up bogus interrupts for u3 i2c...\n");
2140
2141         /* interrupt on this revision of u3 is number 0 and level */
2142         interrupts[0] = 0;
2143         interrupts[1] = 1;
2144         prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupts",
2145                      &interrupts, sizeof(interrupts));
2146         parent = (u32)mpic;
2147         prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
2148                      &parent, sizeof(parent));
2149 }
2150 #else
2151 #define fixup_device_tree_pmac()
2152 #endif
2153
2154 #ifdef CONFIG_PPC_EFIKA
2155 /*
2156  * The MPC5200 FEC driver requires an phy-handle property to tell it how
2157  * to talk to the phy.  If the phy-handle property is missing, then this
2158  * function is called to add the appropriate nodes and link it to the
2159  * ethernet node.
2160  */
2161 static void __init fixup_device_tree_efika_add_phy(void)
2162 {
2163         u32 node;
2164         char prop[64];
2165         int rv;
2166
2167         /* Check if /builtin/ethernet exists - bail if it doesn't */
2168         node = call_prom("finddevice", 1, 1, ADDR("/builtin/ethernet"));
2169         if (!PHANDLE_VALID(node))
2170                 return;
2171
2172         /* Check if the phy-handle property exists - bail if it does */
2173         rv = prom_getprop(node, "phy-handle", prop, sizeof(prop));
2174         if (!rv)
2175                 return;
2176
2177         /*
2178          * At this point the ethernet device doesn't have a phy described.
2179          * Now we need to add the missing phy node and linkage
2180          */
2181
2182         /* Check for an MDIO bus node - if missing then create one */
2183         node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio"));
2184         if (!PHANDLE_VALID(node)) {
2185                 prom_printf("Adding Ethernet MDIO node\n");
2186                 call_prom("interpret", 1, 1,
2187                         " s\" /builtin\" find-device"
2188                         " new-device"
2189                                 " 1 encode-int s\" #address-cells\" property"
2190                                 " 0 encode-int s\" #size-cells\" property"
2191                                 " s\" mdio\" device-name"
2192                                 " s\" fsl,mpc5200b-mdio\" encode-string"
2193                                 " s\" compatible\" property"
2194                                 " 0xf0003000 0x400 reg"
2195                                 " 0x2 encode-int"
2196                                 " 0x5 encode-int encode+"
2197                                 " 0x3 encode-int encode+"
2198                                 " s\" interrupts\" property"
2199                         " finish-device");
2200         };
2201
2202         /* Check for a PHY device node - if missing then create one and
2203          * give it's phandle to the ethernet node */
2204         node = call_prom("finddevice", 1, 1,
2205                          ADDR("/builtin/mdio/ethernet-phy"));
2206         if (!PHANDLE_VALID(node)) {
2207                 prom_printf("Adding Ethernet PHY node\n");
2208                 call_prom("interpret", 1, 1,
2209                         " s\" /builtin/mdio\" find-device"
2210                         " new-device"
2211                                 " s\" ethernet-phy\" device-name"
2212                                 " 0x10 encode-int s\" reg\" property"
2213                                 " my-self"
2214                                 " ihandle>phandle"
2215                         " finish-device"
2216                         " s\" /builtin/ethernet\" find-device"
2217                                 " encode-int"
2218                                 " s\" phy-handle\" property"
2219                         " device-end");
2220         }
2221 }
2222
2223 static void __init fixup_device_tree_efika(void)
2224 {
2225         int sound_irq[3] = { 2, 2, 0 };
2226         int bcomm_irq[3*16] = { 3,0,0, 3,1,0, 3,2,0, 3,3,0,
2227                                 3,4,0, 3,5,0, 3,6,0, 3,7,0,
2228                                 3,8,0, 3,9,0, 3,10,0, 3,11,0,
2229                                 3,12,0, 3,13,0, 3,14,0, 3,15,0 };
2230         u32 node;
2231         char prop[64];
2232         int rv, len;
2233
2234         /* Check if we're really running on a EFIKA */
2235         node = call_prom("finddevice", 1, 1, ADDR("/"));
2236         if (!PHANDLE_VALID(node))
2237                 return;
2238
2239         rv = prom_getprop(node, "model", prop, sizeof(prop));
2240         if (rv == PROM_ERROR)
2241                 return;
2242         if (strcmp(prop, "EFIKA5K2"))
2243                 return;
2244
2245         prom_printf("Applying EFIKA device tree fixups\n");
2246
2247         /* Claiming to be 'chrp' is death */
2248         node = call_prom("finddevice", 1, 1, ADDR("/"));
2249         rv = prom_getprop(node, "device_type", prop, sizeof(prop));
2250         if (rv != PROM_ERROR && (strcmp(prop, "chrp") == 0))
2251                 prom_setprop(node, "/", "device_type", "efika", sizeof("efika"));
2252
2253         /* CODEGEN,description is exposed in /proc/cpuinfo so
2254            fix that too */
2255         rv = prom_getprop(node, "CODEGEN,description", prop, sizeof(prop));
2256         if (rv != PROM_ERROR && (strstr(prop, "CHRP")))
2257                 prom_setprop(node, "/", "CODEGEN,description",
2258                              "Efika 5200B PowerPC System",
2259                              sizeof("Efika 5200B PowerPC System"));
2260
2261         /* Fixup bestcomm interrupts property */
2262         node = call_prom("finddevice", 1, 1, ADDR("/builtin/bestcomm"));
2263         if (PHANDLE_VALID(node)) {
2264                 len = prom_getproplen(node, "interrupts");
2265                 if (len == 12) {
2266                         prom_printf("Fixing bestcomm interrupts property\n");
2267                         prom_setprop(node, "/builtin/bestcom", "interrupts",
2268                                      bcomm_irq, sizeof(bcomm_irq));
2269                 }
2270         }
2271
2272         /* Fixup sound interrupts property */
2273         node = call_prom("finddevice", 1, 1, ADDR("/builtin/sound"));
2274         if (PHANDLE_VALID(node)) {
2275                 rv = prom_getprop(node, "interrupts", prop, sizeof(prop));
2276                 if (rv == PROM_ERROR) {
2277                         prom_printf("Adding sound interrupts property\n");
2278                         prom_setprop(node, "/builtin/sound", "interrupts",
2279                                      sound_irq, sizeof(sound_irq));
2280                 }
2281         }
2282
2283         /* Make sure ethernet phy-handle property exists */
2284         fixup_device_tree_efika_add_phy();
2285 }
2286 #else
2287 #define fixup_device_tree_efika()
2288 #endif
2289
2290 static void __init fixup_device_tree(void)
2291 {
2292         fixup_device_tree_maple();
2293         fixup_device_tree_chrp();
2294         fixup_device_tree_pmac();
2295         fixup_device_tree_efika();
2296 }
2297
2298 static void __init prom_find_boot_cpu(void)
2299 {
2300         struct prom_t *_prom = &RELOC(prom);
2301         u32 getprop_rval;
2302         ihandle prom_cpu;
2303         phandle cpu_pkg;
2304
2305         _prom->cpu = 0;
2306         if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0)
2307                 return;
2308
2309         cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
2310
2311         prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
2312         _prom->cpu = getprop_rval;
2313
2314         prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu);
2315 }
2316
2317 static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
2318 {
2319 #ifdef CONFIG_BLK_DEV_INITRD
2320         struct prom_t *_prom = &RELOC(prom);
2321
2322         if (r3 && r4 && r4 != 0xdeadbeef) {
2323                 unsigned long val;
2324
2325                 RELOC(prom_initrd_start) = is_kernel_addr(r3) ? __pa(r3) : r3;
2326                 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
2327
2328                 val = RELOC(prom_initrd_start);
2329                 prom_setprop(_prom->chosen, "/chosen", "linux,initrd-start",
2330                              &val, sizeof(val));
2331                 val = RELOC(prom_initrd_end);
2332                 prom_setprop(_prom->chosen, "/chosen", "linux,initrd-end",
2333                              &val, sizeof(val));
2334
2335                 reserve_mem(RELOC(prom_initrd_start),
2336                             RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
2337
2338                 prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start));
2339                 prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end));
2340         }
2341 #endif /* CONFIG_BLK_DEV_INITRD */
2342 }
2343
2344 /*
2345  * We enter here early on, when the Open Firmware prom is still
2346  * handling exceptions and the MMU hash table for us.
2347  */
2348
2349 unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2350                                unsigned long pp,
2351                                unsigned long r6, unsigned long r7)
2352 {       
2353         struct prom_t *_prom;
2354         unsigned long hdr;
2355         unsigned long offset = reloc_offset();
2356
2357 #ifdef CONFIG_PPC32
2358         reloc_got2(offset);
2359 #endif
2360
2361         _prom = &RELOC(prom);
2362
2363         /*
2364          * First zero the BSS
2365          */
2366         memset(&RELOC(__bss_start), 0, __bss_stop - __bss_start);
2367
2368         /*
2369          * Init interface to Open Firmware, get some node references,
2370          * like /chosen
2371          */
2372         prom_init_client_services(pp);
2373
2374         /*
2375          * See if this OF is old enough that we need to do explicit maps
2376          * and other workarounds
2377          */
2378         prom_find_mmu();
2379
2380         /*
2381          * Init prom stdout device
2382          */
2383         prom_init_stdout();
2384
2385         /*
2386          * Get default machine type. At this point, we do not differentiate
2387          * between pSeries SMP and pSeries LPAR
2388          */
2389         RELOC(of_platform) = prom_find_machine_type();
2390
2391         /* Bail if this is a kdump kernel. */
2392         if (PHYSICAL_START > 0)
2393                 prom_panic("Error: You can't boot a kdump kernel from OF!\n");
2394
2395         /*
2396          * Check for an initrd
2397          */
2398         prom_check_initrd(r3, r4);
2399
2400 #ifdef CONFIG_PPC_PSERIES
2401         /*
2402          * On pSeries, inform the firmware about our capabilities
2403          */
2404         if (RELOC(of_platform) == PLATFORM_PSERIES ||
2405             RELOC(of_platform) == PLATFORM_PSERIES_LPAR)
2406                 prom_send_capabilities();
2407 #endif
2408
2409         /*
2410          * Copy the CPU hold code
2411          */
2412         if (RELOC(of_platform) != PLATFORM_POWERMAC)
2413                 copy_and_flush(0, KERNELBASE + offset, 0x100, 0);
2414
2415         /*
2416          * Do early parsing of command line
2417          */
2418         early_cmdline_parse();
2419
2420         /*
2421          * Initialize memory management within prom_init
2422          */
2423         prom_init_mem();
2424
2425         /*
2426          * Determine which cpu is actually running right _now_
2427          */
2428         prom_find_boot_cpu();
2429
2430         /* 
2431          * Initialize display devices
2432          */
2433         prom_check_displays();
2434
2435 #ifdef CONFIG_PPC64
2436         /*
2437          * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
2438          * that uses the allocator, we need to make sure we get the top of memory
2439          * available for us here...
2440          */
2441         if (RELOC(of_platform) == PLATFORM_PSERIES)
2442                 prom_initialize_tce_table();
2443 #endif
2444
2445         /*
2446          * On non-powermacs, try to instantiate RTAS and puts all CPUs
2447          * in spin-loops. PowerMacs don't have a working RTAS and use
2448          * a different way to spin CPUs
2449          */
2450         if (RELOC(of_platform) != PLATFORM_POWERMAC) {
2451                 prom_instantiate_rtas();
2452                 prom_hold_cpus();
2453         }
2454
2455         /*
2456          * Fill in some infos for use by the kernel later on
2457          */
2458 #ifdef CONFIG_PPC64
2459         if (RELOC(prom_iommu_off))
2460                 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off",
2461                              NULL, 0);
2462
2463         if (RELOC(prom_iommu_force_on))
2464                 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-force-on",
2465                              NULL, 0);
2466
2467         if (RELOC(prom_tce_alloc_start)) {
2468                 prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-start",
2469                              &RELOC(prom_tce_alloc_start),
2470                              sizeof(prom_tce_alloc_start));
2471                 prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-end",
2472                              &RELOC(prom_tce_alloc_end),
2473                              sizeof(prom_tce_alloc_end));
2474         }
2475 #endif
2476
2477         /*
2478          * Fixup any known bugs in the device-tree
2479          */
2480         fixup_device_tree();
2481
2482         /*
2483          * Now finally create the flattened device-tree
2484          */
2485         prom_printf("copying OF device tree ...\n");
2486         flatten_device_tree();
2487
2488         /*
2489          * in case stdin is USB and still active on IBM machines...
2490          * Unfortunately quiesce crashes on some powermacs if we have
2491          * closed stdin already (in particular the powerbook 101).
2492          */
2493         if (RELOC(of_platform) != PLATFORM_POWERMAC)
2494                 prom_close_stdin();
2495
2496         /*
2497          * Call OF "quiesce" method to shut down pending DMA's from
2498          * devices etc...
2499          */
2500         prom_printf("Calling quiesce ...\n");
2501         call_prom("quiesce", 0, 0);
2502
2503         /*
2504          * And finally, call the kernel passing it the flattened device
2505          * tree and NULL as r5, thus triggering the new entry point which
2506          * is common to us and kexec
2507          */
2508         hdr = RELOC(dt_header_start);
2509         prom_printf("returning from prom_init\n");
2510         prom_debug("->dt_header_start=0x%x\n", hdr);
2511
2512 #ifdef CONFIG_PPC32
2513         reloc_got2(-offset);
2514 #endif
2515
2516         __start(hdr, KERNELBASE + offset, 0);
2517
2518         return 0;
2519 }