prom.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:66k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* - undefined for user space
  2.  * 
  3.  *
  4.  * Procedures for interfacing to Open Firmware.
  5.  *
  6.  * Paul Mackerras August 1996.
  7.  * Copyright (C) 1996 Paul Mackerras.
  8.  * 
  9.  *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
  10.  *    {engebret|bergner}@us.ibm.com 
  11.  *
  12.  *      This program is free software; you can redistribute it and/or
  13.  *      modify it under the terms of the GNU General Public License
  14.  *      as published by the Free Software Foundation; either version
  15.  *      2 of the License, or (at your option) any later version.
  16.  */
  17. #if 0
  18. #define DEBUG_YABOOT
  19. #endif
  20. #if 0
  21. #define DEBUG_PROM
  22. #endif
  23. #include <stdarg.h>
  24. #include <linux/config.h>
  25. #include <linux/kernel.h>
  26. #include <linux/string.h>
  27. #include <linux/init.h>
  28. #include <linux/version.h>
  29. #include <linux/threads.h>
  30. #include <linux/spinlock.h>
  31. #include <linux/blk.h>
  32. #ifdef DEBUG_YABOOT
  33. #define call_yaboot(FUNC,...) 
  34. do { 
  35. if (FUNC) {
  36. struct prom_t *_prom = PTRRELOC(&prom);
  37. unsigned long prom_entry = _prom->entry;
  38. _prom->entry = (unsigned long)(FUNC);
  39. enter_prom(__VA_ARGS__); 
  40. _prom->entry = prom_entry;
  41. }
  42. } while (0)
  43. #else
  44. #define call_yaboot(FUNC,...) do { ; } while (0)
  45. #endif
  46. #include <asm/init.h>
  47. #include <linux/types.h>
  48. #include <linux/pci.h>
  49. #include <asm/prom.h>
  50. #include <asm/rtas.h>
  51. #include <asm/lmb.h>
  52. #include <asm/abs_addr.h>
  53. #include <asm/page.h>
  54. #include <asm/processor.h>
  55. #include <asm/irq.h>
  56. #include <asm/io.h>
  57. #include <asm/smp.h>
  58. #include <asm/system.h>
  59. #include <asm/mmu.h>
  60. #include <asm/pgtable.h>
  61. #include <asm/bitops.h>
  62. #include <asm/naca.h>
  63. #include <asm/pci.h>
  64. #include "open_pic.h"
  65. #include <asm/bootinfo.h>
  66. #include <asm/ppcdebug.h>
  67. #ifdef CONFIG_FB
  68. #include <asm/linux_logo.h>
  69. #endif
  70. extern char _end[];
  71. /*
  72.  * prom_init() is called very early on, before the kernel text
  73.  * and data have been mapped to KERNELBASE.  At this point the code
  74.  * is running at whatever address it has been loaded at, so
  75.  * references to extern and static variables must be relocated
  76.  * explicitly.  The procedure reloc_offset() returns the address
  77.  * we're currently running at minus the address we were linked at.
  78.  * (Note that strings count as static variables.)
  79.  *
  80.  * Because OF may have mapped I/O devices into the area starting at
  81.  * KERNELBASE, particularly on CHRP machines, we can't safely call
  82.  * OF once the kernel has been mapped to KERNELBASE.  Therefore all
  83.  * OF calls should be done within prom_init(), and prom_init()
  84.  * and all routines called within it must be careful to relocate
  85.  * references as necessary.
  86.  *
  87.  * Note that the bss is cleared *after* prom_init runs, so we have
  88.  * to make sure that any static or extern variables it accesses
  89.  * are put in the data segment.
  90.  */
  91. #define PROM_BUG() do { 
  92.         prom_print(RELOC("kernel BUG at ")); 
  93.         prom_print(RELOC(__FILE__)); 
  94.         prom_print(RELOC(":")); 
  95.         prom_print_hex(__LINE__); 
  96.         prom_print(RELOC("!n")); 
  97.         __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); 
  98. } while (0)
  99. struct pci_reg_property {
  100. struct pci_address addr;
  101. u32 size_hi;
  102. u32 size_lo;
  103. };
  104. struct isa_reg_property {
  105. u32 space;
  106. u32 address;
  107. u32 size;
  108. };
  109. struct pci_intr_map {
  110. struct pci_address addr;
  111. u32 dunno;
  112. phandle int_ctrler;
  113. u32 intr;
  114. };
  115. typedef unsigned long interpret_func(struct device_node *, unsigned long,
  116.      int, int);
  117. #if 0
  118. static interpret_func interpret_pci_props;
  119. #endif
  120. static unsigned long interpret_pci_props(struct device_node *, unsigned long,
  121.  int, int);
  122. static interpret_func interpret_isa_props;
  123. static interpret_func interpret_root_props;
  124. #ifndef FB_MAX /* avoid pulling in all of the fb stuff */
  125. #define FB_MAX 8
  126. #endif
  127. struct prom_t prom = {
  128. 0, /* entry */
  129. 0, /* chosen */
  130. 0, /* cpu */
  131. 0, /* stdout */
  132. 0, /* disp_node */
  133. {0,0,0,{0},NULL}, /* args */
  134. 0, /* version */
  135. 32, /* encode_phys_size */
  136. 0 /* bi_rec pointer */
  137. #ifdef DEBUG_YABOOT
  138. ,NULL /* yaboot */
  139. #endif
  140. };
  141. char *prom_display_paths[FB_MAX] __initdata = { 0, };
  142. unsigned int prom_num_displays = 0;
  143. char *of_stdout_device = 0;
  144. extern struct rtas_t rtas;
  145. extern unsigned long klimit;
  146. extern unsigned long embedded_sysmap_end;
  147. extern struct lmb lmb;
  148. #ifdef CONFIG_MSCHUNKS
  149. extern struct msChunks msChunks;
  150. #endif /* CONFIG_MSCHUNKS */
  151. #define MAX_PHB 16 * 3  // 16 Towers * 3 PHBs/tower
  152. struct _of_tce_table of_tce_table[MAX_PHB + 1] = {{0, 0, 0}};
  153. char *bootpath = 0;
  154. char *bootdevice = 0;
  155. struct device_node *allnodes = 0;
  156. #define UNDEFINED_IRQ 0xffff
  157. unsigned short real_irq_to_virt_map[NR_HW_IRQS];
  158. unsigned short virt_irq_to_real_map[NR_IRQS];
  159. int last_virt_irq = 2; /* index of last virt_irq.  Skip through IPI */
  160. static unsigned long call_prom(const char *service, int nargs, int nret, ...);
  161. static void prom_exit(void);
  162. static unsigned long copy_device_tree(unsigned long);
  163. static unsigned long inspect_node(phandle, struct device_node *, unsigned long,
  164.   unsigned long, struct device_node ***);
  165. static unsigned long finish_node(struct device_node *, unsigned long,
  166.  interpret_func *, int, int);
  167. static unsigned long finish_node_interrupts(struct device_node *, unsigned long);
  168. static unsigned long check_display(unsigned long);
  169. static int prom_next_node(phandle *);
  170. static struct bi_record * prom_bi_rec_verify(struct bi_record *);
  171. static unsigned long prom_bi_rec_reserve(unsigned long);
  172. static struct device_node *find_phandle(phandle);
  173. #ifdef CONFIG_MSCHUNKS
  174. static unsigned long prom_initialize_mschunks(unsigned long);
  175. #ifdef DEBUG_PROM
  176. void prom_dump_mschunks_mapping(void);
  177. #endif /* DEBUG_PROM */
  178. #endif /* CONFIG_MSCHUNKS */
  179. #ifdef DEBUG_PROM
  180. void prom_dump_lmb(void);
  181. #endif
  182. extern unsigned long reloc_offset(void);
  183. extern void enter_prom(void *dummy,...);
  184. void cacheable_memzero(void *, unsigned int);
  185. #ifndef CONFIG_CMDLINE
  186. #define CONFIG_CMDLINE ""
  187. #endif
  188. char cmd_line[512] = CONFIG_CMDLINE;
  189. unsigned long dev_tree_size;
  190. #ifdef CONFIG_HMT
  191. struct {
  192. unsigned int pir;
  193. unsigned int threadid;
  194. } hmt_thread_data[NR_CPUS] = {0};
  195. #endif /* CONFIG_HMT */
  196. char testString[] = "LINUXn"; 
  197. /* This is the one and *ONLY* place where we actually call open
  198.  * firmware from, since we need to make sure we're running in 32b
  199.  * mode when we do.  We switch back to 64b mode upon return.
  200.  */
  201. static unsigned long __init
  202. call_prom(const char *service, int nargs, int nret, ...)
  203. {
  204. int i;
  205. unsigned long offset = reloc_offset();
  206. struct prom_t *_prom = PTRRELOC(&prom);
  207. va_list list;
  208.         
  209. _prom->args.service = (u32)LONG_LSW(service);
  210. _prom->args.nargs = nargs;
  211. _prom->args.nret = nret;
  212.         _prom->args.rets = (prom_arg_t *)&(_prom->args.args[nargs]);
  213.         va_start(list, nret);
  214. for (i=0; i < nargs ;i++)
  215. _prom->args.args[i] = (prom_arg_t)LONG_LSW(va_arg(list, unsigned long));
  216.         va_end(list);
  217. for (i=0; i < nret ;i++)
  218. _prom->args.rets[i] = 0;
  219. enter_prom(&_prom->args);
  220. return (unsigned long)((nret > 0) ? _prom->args.rets[0] : 0);
  221. }
  222. static void __init
  223. prom_exit()
  224. {
  225. unsigned long offset = reloc_offset();
  226. call_prom(RELOC("exit"), 0, 0);
  227. for (;;) /* should never get here */
  228. ;
  229. }
  230. void __init
  231. prom_enter(void)
  232. {
  233. unsigned long offset = reloc_offset();
  234. call_prom(RELOC("enter"), 0, 0);
  235. }
  236. void __init
  237. prom_print(const char *msg)
  238. {
  239. const char *p, *q;
  240. unsigned long offset = reloc_offset();
  241. struct prom_t *_prom = PTRRELOC(&prom);
  242. if (_prom->stdout == 0)
  243. return;
  244. for (p = msg; *p != 0; p = q) {
  245. for (q = p; *q != 0 && *q != 'n'; ++q)
  246. ;
  247. if (q > p)
  248. call_prom(RELOC("write"), 3, 1, _prom->stdout,
  249.   p, q - p);
  250. if (*q != 0) {
  251. ++q;
  252. call_prom(RELOC("write"), 3, 1, _prom->stdout,
  253.   RELOC("rn"), 2);
  254. }
  255. }
  256. }
  257. void
  258. prom_print_hex(unsigned long val)
  259. {
  260.         int i, nibbles = sizeof(val)*2;
  261.         char buf[sizeof(val)*2+1];
  262.         for (i = nibbles-1;  i >= 0;  i--) {
  263.                 buf[i] = (val & 0xf) + '0';
  264.                 if (buf[i] > '9')
  265.                     buf[i] += ('a'-'0'-10);
  266.                 val >>= 4;
  267.         }
  268.         buf[nibbles] = '';
  269. prom_print(buf);
  270. }
  271. void
  272. prom_print_nl(void)
  273. {
  274. unsigned long offset = reloc_offset();
  275. prom_print(RELOC("n"));
  276. }
  277. static unsigned long
  278. prom_initialize_naca(unsigned long mem)
  279. {
  280. phandle node;
  281. char type[64];
  282.         unsigned long num_cpus = 0;
  283.         unsigned long offset = reloc_offset();
  284. struct prom_t *_prom = PTRRELOC(&prom);
  285.         struct naca_struct *_naca = RELOC(naca);
  286. /* NOTE: _naca->debug_switch is already initialized. */
  287. #ifdef DEBUG_PROM
  288. prom_print(RELOC("prom_initialize_naca: start...n"));
  289. #endif
  290. _naca->pftSize = 0; /* ilog2 of htab size.  computed below. */
  291.         for (node = 0; prom_next_node(&node); ) {
  292.                 type[0] = 0;
  293.                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
  294.                           type, sizeof(type));
  295.                 if (!strcmp(type, RELOC("cpu"))) {
  296. num_cpus += 1;
  297. /* We're assuming *all* of the CPUs have the same
  298.  * d-cache and i-cache sizes... -Peter
  299.  */
  300. if ( num_cpus == 1 ) {
  301. u32 size, lsize, sets;
  302. call_prom(RELOC("getprop"), 4, 1, node,
  303.   RELOC("d-cache-size"),
  304.   &size, sizeof(size));
  305. call_prom(RELOC("getprop"), 4, 1, node,
  306.   RELOC("d-cache-line-size"),
  307.   &lsize, sizeof(lsize));
  308. call_prom(RELOC("getprop"), 4, 1, node,
  309.   RELOC("d-cache-sets"),
  310.   &sets, sizeof(sets));
  311. _naca->dCacheL1Size         = size;
  312. _naca->dCacheL1LineSize     = lsize;
  313. _naca->dCacheL1LogLineSize  = __ilog2(lsize);
  314. _naca->dCacheL1LinesPerPage = PAGE_SIZE/lsize;
  315. _naca->dCacheL1Assoc = size / lsize / sets;
  316. call_prom(RELOC("getprop"), 4, 1, node,
  317.   RELOC("i-cache-line-size"),
  318.   &size, sizeof(size));
  319. call_prom(RELOC("getprop"), 4, 1, node,
  320.   RELOC("i-cache-line-size"),
  321.   &lsize, sizeof(lsize));
  322. call_prom(RELOC("getprop"), 4, 1, node,
  323.   RELOC("i-cache-sets"),
  324.   &sets, sizeof(sets));
  325. _naca->iCacheL1Size         = size;
  326. _naca->iCacheL1LineSize     = lsize;
  327. _naca->iCacheL1LogLineSize  = __ilog2(lsize);
  328. _naca->iCacheL1LinesPerPage = PAGE_SIZE/lsize;
  329. _naca->iCacheL1Assoc = size / lsize / sets;
  330. if (_naca->platform == PLATFORM_PSERIES_LPAR) {
  331. u32 pft_size[2];
  332. call_prom(RELOC("getprop"), 4, 1, node, 
  333.   RELOC("ibm,pft-size"),
  334.   &pft_size, sizeof(pft_size));
  335. /* pft_size[0] is the NUMA CEC cookie */
  336. _naca->pftSize = pft_size[1];
  337. }
  338. }
  339.                 } else if (!strcmp(type, RELOC("serial"))) {
  340. phandle isa, pci;
  341. struct isa_reg_property reg;
  342. union pci_range ranges;
  343. type[0] = 0;
  344. call_prom(RELOC("getprop"), 4, 1, node,
  345.   RELOC("ibm,aix-loc"), type, sizeof(type));
  346. if (strcmp(type, RELOC("S1")))
  347. continue;
  348. call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
  349.   &reg, sizeof(reg));
  350. isa = call_prom(RELOC("parent"), 1, 1, node);
  351. if (!isa)
  352. PROM_BUG();
  353. pci = call_prom(RELOC("parent"), 1, 1, isa);
  354. if (!pci)
  355. PROM_BUG();
  356. call_prom(RELOC("getprop"), 4, 1, pci, RELOC("ranges"),
  357.   &ranges, sizeof(ranges));
  358. if ( _prom->encode_phys_size == 32 )
  359. _naca->serialPortAddr = ranges.pci32.phys+reg.address;
  360. else {
  361. _naca->serialPortAddr = 
  362. ((((unsigned long)ranges.pci64.phys_hi) << 32) |
  363.  (ranges.pci64.phys_lo)) + reg.address;
  364. }
  365.                 }
  366. }
  367. _naca->interrupt_controller = IC_INVALID;
  368.         for (node = 0; prom_next_node(&node); ) {
  369.                 type[0] = 0;
  370.                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("name"),
  371.                           type, sizeof(type));
  372.                 if (strcmp(type, RELOC("interrupt-controller"))) {
  373. continue;
  374. }
  375.                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("compatible"),
  376.                           type, sizeof(type));
  377.                 if (strstr(type, RELOC("open-pic"))) {
  378. _naca->interrupt_controller = IC_OPEN_PIC;
  379. } else if (strstr(type, RELOC("ppc-xicp"))) {
  380. _naca->interrupt_controller = IC_PPC_XIC;
  381. } else {
  382. prom_print(RELOC("prom: failed to recognize interrupt-controllern"));
  383. }
  384. break;
  385. }
  386. if (_naca->interrupt_controller == IC_INVALID) {
  387. prom_print(RELOC("prom: failed to find interrupt-controllern"));
  388. PROM_BUG();
  389. }
  390. /* We gotta have at least 1 cpu... */
  391.         if ( (_naca->processorCount = num_cpus) < 1 )
  392.                 PROM_BUG();
  393. _naca->physicalMemorySize = lmb_phys_mem_size();
  394. if (_naca->platform == PLATFORM_PSERIES) {
  395. unsigned long rnd_mem_size, pteg_count;
  396. /* round mem_size up to next power of 2 */
  397. rnd_mem_size = 1UL << __ilog2(_naca->physicalMemorySize);
  398. if (rnd_mem_size < _naca->physicalMemorySize)
  399. rnd_mem_size <<= 1;
  400. /* # pages / 2 */
  401. pteg_count = (rnd_mem_size >> (12 + 1));
  402. _naca->pftSize = __ilog2(pteg_count << 7);
  403. }
  404. if (_naca->pftSize == 0) {
  405. prom_print(RELOC("prom: failed to compute pftSize!n"));
  406. PROM_BUG();
  407. }
  408. /* 
  409.  * Hardcode to GP size.  I am not sure where to get this info
  410.  * in general, as there does not appear to be a slb-size OF
  411.  * entry.  At least in Condor and earlier.  DRENG 
  412.  */
  413. _naca->slb_size = 64;
  414. /* Add an eye catcher and the naca layout version number */
  415. strcpy(_naca->eye_catcher, RELOC("PPC64"));
  416. _naca->version     = 1;
  417. _naca->processor   = _get_PVR() >> 16;
  418. #ifdef DEBUG_PROM
  419.         prom_print(RELOC("naca->processorCount       = 0x"));
  420.         prom_print_hex(_naca->processorCount);
  421.         prom_print_nl();
  422.         prom_print(RELOC("naca->physicalMemorySize   = 0x"));
  423.         prom_print_hex(_naca->physicalMemorySize);
  424.         prom_print_nl();
  425.         prom_print(RELOC("naca->pftSize              = 0x"));
  426.         prom_print_hex(_naca->pftSize);
  427.         prom_print_nl();
  428.         prom_print(RELOC("naca->dCacheL1LineSize     = 0x"));
  429.         prom_print_hex(_naca->dCacheL1LineSize);
  430.         prom_print_nl();
  431.         prom_print(RELOC("naca->dCacheL1LogLineSize  = 0x"));
  432.         prom_print_hex(_naca->dCacheL1LogLineSize);
  433.         prom_print_nl();
  434.         prom_print(RELOC("naca->dCacheL1LinesPerPage = 0x"));
  435.         prom_print_hex(_naca->dCacheL1LinesPerPage);
  436.         prom_print_nl();
  437.         prom_print(RELOC("naca->iCacheL1LineSize     = 0x"));
  438.         prom_print_hex(_naca->iCacheL1LineSize);
  439.         prom_print_nl();
  440.         prom_print(RELOC("naca->iCacheL1LogLineSize  = 0x"));
  441.         prom_print_hex(_naca->iCacheL1LogLineSize);
  442.         prom_print_nl();
  443.         prom_print(RELOC("naca->iCacheL1LinesPerPage = 0x"));
  444.         prom_print_hex(_naca->iCacheL1LinesPerPage);
  445.         prom_print_nl();
  446.         prom_print(RELOC("naca->serialPortAddr       = 0x"));
  447.         prom_print_hex(_naca->serialPortAddr);
  448.         prom_print_nl();
  449.         prom_print(RELOC("naca->interrupt_controller = 0x"));
  450.         prom_print_hex(_naca->interrupt_controller);
  451.         prom_print_nl();
  452.         prom_print(RELOC("naca->platform             = 0x"));
  453.         prom_print_hex(_naca->platform);
  454.         prom_print_nl();
  455. prom_print(RELOC("prom_initialize_naca: end...n"));
  456. #endif
  457. return mem;
  458. }
  459. static unsigned long __init
  460. prom_initialize_lmb(unsigned long mem)
  461. {
  462. phandle node;
  463. char type[64];
  464.         unsigned long i, offset = reloc_offset();
  465. struct prom_t *_prom = PTRRELOC(&prom);
  466. union lmb_reg_property reg;
  467. unsigned long lmb_base, lmb_size;
  468. unsigned long num_regs, bytes_per_reg = (_prom->encode_phys_size*2)/8;
  469. #ifdef CONFIG_MSCHUNKS
  470. unsigned long max_addr = 0;
  471. #if 1
  472. /* Fix me: 630 3G-4G IO hack here... -Peter (PPPBBB) */
  473. unsigned long io_base = 3UL<<30;
  474. unsigned long io_size = 1UL<<30;
  475. unsigned long have_630 = 1; /* assume we have a 630 */
  476. #else
  477. unsigned long io_base = <real io base here>;
  478. unsigned long io_size = <real io size here>;
  479. #endif
  480. #endif /* CONFIG_MSCHUNKS */
  481. lmb_init();
  482.         for (node = 0; prom_next_node(&node); ) {
  483.                 type[0] = 0;
  484.                 call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
  485.                           type, sizeof(type));
  486.                 if (strcmp(type, RELOC("memory")))
  487. continue;
  488. num_regs = call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
  489. &reg, sizeof(reg)) / bytes_per_reg;
  490. for (i=0; i < num_regs ;i++) {
  491. if (_prom->encode_phys_size == 32) {
  492. lmb_base = reg.addr32[i].address;
  493. lmb_size = reg.addr32[i].size;
  494. } else {
  495. lmb_base = reg.addr64[i].address;
  496. lmb_size = reg.addr64[i].size;
  497. }
  498. #ifdef CONFIG_MSCHUNKS
  499. if ( lmb_addrs_overlap(lmb_base,lmb_size,
  500. io_base,io_size) ) {
  501. /* If we really have dram here, then we don't
  502.    * have a 630! -Peter
  503.    */
  504. have_630 = 0;
  505. }
  506. #endif /* CONFIG_MSCHUNKS */
  507. if ( lmb_add(lmb_base, lmb_size) < 0 )
  508. prom_print(RELOC("Too many LMB's, discarding this one...n"));
  509. #ifdef CONFIG_MSCHUNKS
  510. else if ( max_addr < (lmb_base+lmb_size-1) )
  511. max_addr = lmb_base+lmb_size-1;
  512. #endif /* CONFIG_MSCHUNKS */
  513. }
  514. }
  515. #ifdef CONFIG_MSCHUNKS
  516. if ( have_630 && lmb_addrs_overlap(0,max_addr,io_base,io_size) )
  517. lmb_add_io(io_base, io_size);
  518. #endif /* CONFIG_MSCHUNKS */
  519. lmb_analyze();
  520. #ifdef DEBUG_PROM
  521. prom_dump_lmb();
  522. #endif /* DEBUG_PROM */
  523. #ifdef CONFIG_MSCHUNKS
  524. mem = prom_initialize_mschunks(mem);
  525. #ifdef DEBUG_PROM
  526. prom_dump_mschunks_mapping();
  527. #endif /* DEBUG_PROM */
  528. #endif /* CONFIG_MSCHUNKS */
  529. return mem;
  530. }
  531. static void __init
  532. prom_instantiate_rtas(void)
  533. {
  534. unsigned long offset = reloc_offset();
  535. struct prom_t *_prom = PTRRELOC(&prom);
  536. struct rtas_t *_rtas = PTRRELOC(&rtas);
  537. struct naca_struct *_naca = RELOC(naca);
  538. ihandle prom_rtas;
  539.         u32 getprop_rval;
  540. #ifdef DEBUG_PROM
  541. prom_print(RELOC("prom_instantiate_rtas: start...n"));
  542. #endif
  543. prom_rtas = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas"));
  544. if (prom_rtas != (ihandle) -1) {
  545. char hypertas_funcs[1024];
  546. int  rc; 
  547. if ((rc = call_prom(RELOC("getprop"), 
  548.   4, 1, prom_rtas,
  549.   RELOC("ibm,hypertas-functions"), 
  550.   hypertas_funcs, 
  551.   sizeof(hypertas_funcs))) > 0) {
  552. _naca->platform = PLATFORM_PSERIES_LPAR;
  553. }
  554. call_prom(RELOC("getprop"), 
  555.   4, 1, prom_rtas,
  556.   RELOC("rtas-size"), 
  557.   &getprop_rval, 
  558.   sizeof(getprop_rval));
  559.         _rtas->size = getprop_rval;
  560. prom_print(RELOC("instantiating rtas"));
  561. if (_rtas->size != 0) {
  562. unsigned long rtas_region = RTAS_INSTANTIATE_MAX;
  563. /* Grab some space within the first RTAS_INSTANTIATE_MAX bytes
  564.  * of physical memory (or within the RMO region) because RTAS
  565.  * runs in 32-bit mode and relocate off.
  566.  */
  567. if ( _naca->platform == PLATFORM_PSERIES_LPAR ) {
  568. struct lmb *_lmb  = PTRRELOC(&lmb);
  569. rtas_region = min(_lmb->rmo_size, RTAS_INSTANTIATE_MAX);
  570. }
  571. _rtas->base = lmb_alloc_base(_rtas->size, PAGE_SIZE, rtas_region);
  572. prom_print(RELOC(" at 0x"));
  573. prom_print_hex(_rtas->base);
  574. prom_rtas = (ihandle)call_prom(RELOC("open"), 
  575.        1, 1, RELOC("/rtas"));
  576. prom_print(RELOC("..."));
  577. if ((long)call_prom(RELOC("call-method"), 3, 2,
  578.       RELOC("instantiate-rtas"),
  579.       prom_rtas,
  580.       _rtas->base) >= 0) {
  581. _rtas->entry = (long)_prom->args.rets[1];
  582. }
  583. }
  584. if (_rtas->entry <= 0) {
  585. prom_print(RELOC(" failedn"));
  586. } else {
  587. prom_print(RELOC(" donen"));
  588. }
  589. #ifdef DEBUG_PROM
  590.          prom_print(RELOC("rtas->base                 = 0x"));
  591.          prom_print_hex(_rtas->base);
  592.          prom_print_nl();
  593.          prom_print(RELOC("rtas->entry                = 0x"));
  594.          prom_print_hex(_rtas->entry);
  595.          prom_print_nl();
  596.          prom_print(RELOC("rtas->size                 = 0x"));
  597.          prom_print_hex(_rtas->size);
  598.          prom_print_nl();
  599. #endif
  600. }
  601. #ifdef DEBUG_PROM
  602. prom_print(RELOC("prom_instantiate_rtas: end...n"));
  603. #endif
  604. }
  605. unsigned long prom_strtoul(const char *cp)
  606. {
  607. unsigned long result = 0,value;
  608. while (*cp) {
  609. value = *cp-'0';
  610. result = result*10 + value;
  611. cp++;
  612. return result;
  613. }
  614. #ifdef CONFIG_MSCHUNKS
  615. static unsigned long
  616. prom_initialize_mschunks(unsigned long mem)
  617. {
  618.         unsigned long offset = reloc_offset();
  619. struct lmb *_lmb  = PTRRELOC(&lmb);
  620. struct msChunks *_msChunks = PTRRELOC(&msChunks);
  621. unsigned long i, pchunk = 0;
  622. unsigned long addr_range = _lmb->memory.size + _lmb->memory.iosize;
  623. unsigned long chunk_size = _lmb->memory.lcd_size;
  624. mem = msChunks_alloc(mem, addr_range / chunk_size, chunk_size);
  625. /* First create phys -> abs mapping for memory/dram */
  626. for (i=0; i < _lmb->memory.cnt ;i++) {
  627. unsigned long base = _lmb->memory.region[i].base;
  628. unsigned long size = _lmb->memory.region[i].size;
  629. unsigned long achunk = addr_to_chunk(base);
  630. unsigned long end_achunk = addr_to_chunk(base+size);
  631. if(_lmb->memory.region[i].type != LMB_MEMORY_AREA)
  632. continue;
  633. _lmb->memory.region[i].physbase = chunk_to_addr(pchunk);
  634. for (; achunk < end_achunk ;) {
  635. PTRRELOC(_msChunks->abs)[pchunk++] = achunk++;
  636. }
  637. }
  638. #ifdef CONFIG_MSCHUNKS
  639. /* Now create phys -> abs mapping for IO */
  640. for (i=0; i < _lmb->memory.cnt ;i++) {
  641. unsigned long base = _lmb->memory.region[i].base;
  642. unsigned long size = _lmb->memory.region[i].size;
  643. unsigned long achunk = addr_to_chunk(base);
  644. unsigned long end_achunk = addr_to_chunk(base+size);
  645. if(_lmb->memory.region[i].type != LMB_IO_AREA)
  646. continue;
  647. _lmb->memory.region[i].physbase = chunk_to_addr(pchunk);
  648. for (; achunk < end_achunk ;) {
  649. PTRRELOC(_msChunks->abs)[pchunk++] = achunk++;
  650. }
  651. }
  652. #endif /* CONFIG_MSCHUNKS */
  653. return mem;
  654. }
  655. #ifdef DEBUG_PROM
  656. void
  657. prom_dump_mschunks_mapping(void)
  658. {
  659.         unsigned long offset = reloc_offset();
  660. struct msChunks *_msChunks = PTRRELOC(&msChunks);
  661. unsigned long chunk;
  662.         prom_print(RELOC("nprom_dump_mschunks_mapping:n"));
  663.         prom_print(RELOC("    msChunks.num_chunks         = 0x"));
  664.         prom_print_hex(_msChunks->num_chunks);
  665. prom_print_nl();
  666.         prom_print(RELOC("    msChunks.chunk_size         = 0x"));
  667.         prom_print_hex(_msChunks->chunk_size);
  668. prom_print_nl();
  669.         prom_print(RELOC("    msChunks.chunk_shift        = 0x"));
  670.         prom_print_hex(_msChunks->chunk_shift);
  671. prom_print_nl();
  672.         prom_print(RELOC("    msChunks.chunk_mask         = 0x"));
  673.         prom_print_hex(_msChunks->chunk_mask);
  674. prom_print_nl();
  675.         prom_print(RELOC("    msChunks.abs                = 0x"));
  676.         prom_print_hex(_msChunks->abs);
  677. prom_print_nl();
  678.         prom_print(RELOC("    msChunks mapping:n"));
  679. for(chunk=0; chunk < _msChunks->num_chunks ;chunk++) {
  680.          prom_print(RELOC("        phys 0x"));
  681.          prom_print_hex(chunk);
  682.          prom_print(RELOC(" -> abs 0x"));
  683.          prom_print_hex(PTRRELOC(_msChunks->abs)[chunk]);
  684. prom_print_nl();
  685. }
  686. }
  687. #endif /* DEBUG_PROM */
  688. #endif /* CONFIG_MSCHUNKS */
  689. #ifdef DEBUG_PROM
  690. void
  691. prom_dump_lmb(void)
  692. {
  693.         unsigned long i;
  694.         unsigned long offset = reloc_offset();
  695. struct lmb *_lmb  = PTRRELOC(&lmb);
  696.         prom_print(RELOC("nprom_dump_lmb:n"));
  697.         prom_print(RELOC("    memory.cnt                  = 0x"));
  698.         prom_print_hex(_lmb->memory.cnt);
  699. prom_print_nl();
  700.         prom_print(RELOC("    memory.size                 = 0x"));
  701.         prom_print_hex(_lmb->memory.size);
  702. prom_print_nl();
  703.         prom_print(RELOC("    memory.lcd_size             = 0x"));
  704.         prom_print_hex(_lmb->memory.lcd_size);
  705. prom_print_nl();
  706.         for (i=0; i < _lmb->memory.cnt ;i++) {
  707.                 prom_print(RELOC("    memory.region[0x"));
  708. prom_print_hex(i);
  709. prom_print(RELOC("].base       = 0x"));
  710.                 prom_print_hex(_lmb->memory.region[i].base);
  711. prom_print_nl();
  712.                 prom_print(RELOC("                      .physbase = 0x"));
  713.                 prom_print_hex(_lmb->memory.region[i].physbase);
  714. prom_print_nl();
  715.                 prom_print(RELOC("                      .size     = 0x"));
  716.                 prom_print_hex(_lmb->memory.region[i].size);
  717. prom_print_nl();
  718.                 prom_print(RELOC("                      .type     = 0x"));
  719.                 prom_print_hex(_lmb->memory.region[i].type);
  720. prom_print_nl();
  721.         }
  722. prom_print_nl();
  723.         prom_print(RELOC("    reserved.cnt                  = 0x"));
  724.         prom_print_hex(_lmb->reserved.cnt);
  725. prom_print_nl();
  726.         prom_print(RELOC("    reserved.size                 = 0x"));
  727.         prom_print_hex(_lmb->reserved.size);
  728. prom_print_nl();
  729.         prom_print(RELOC("    reserved.lcd_size             = 0x"));
  730.         prom_print_hex(_lmb->reserved.lcd_size);
  731. prom_print_nl();
  732.         for (i=0; i < _lmb->reserved.cnt ;i++) {
  733.                 prom_print(RELOC("    reserved.region[0x"));
  734. prom_print_hex(i);
  735. prom_print(RELOC("].base       = 0x"));
  736.                 prom_print_hex(_lmb->reserved.region[i].base);
  737. prom_print_nl();
  738.                 prom_print(RELOC("                      .physbase = 0x"));
  739.                 prom_print_hex(_lmb->reserved.region[i].physbase);
  740. prom_print_nl();
  741.                 prom_print(RELOC("                      .size     = 0x"));
  742.                 prom_print_hex(_lmb->reserved.region[i].size);
  743. prom_print_nl();
  744.                 prom_print(RELOC("                      .type     = 0x"));
  745.                 prom_print_hex(_lmb->reserved.region[i].type);
  746. prom_print_nl();
  747.         }
  748. }
  749. #endif /* DEBUG_PROM */
  750. void
  751. prom_initialize_tce_table(void)
  752. {
  753. phandle node;
  754. ihandle phb_node;
  755.         unsigned long offset = reloc_offset();
  756. char compatible[64], path[64], type[64], model[64];
  757. unsigned long i, table = 0;
  758. unsigned long base, vbase, align;
  759. unsigned int minalign, minsize;
  760. struct _of_tce_table *prom_tce_table = RELOC(of_tce_table);
  761. unsigned long tce_entry, *tce_entryp;
  762. #ifdef DEBUG_PROM
  763. prom_print(RELOC("starting prom_initialize_tce_tablen"));
  764. #endif
  765. /* Search all nodes looking for PHBs. */
  766. for (node = 0; prom_next_node(&node); ) {
  767. compatible[0] = 0;
  768. type[0] = 0;
  769. model[0] = 0;
  770. call_prom(RELOC("getprop"), 4, 1, node, RELOC("compatible"),
  771.   compatible, sizeof(compatible));
  772. call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
  773.   type, sizeof(type));
  774. call_prom(RELOC("getprop"), 4, 1, node, RELOC("model"),
  775.   model, sizeof(model));
  776. /* Keep the old logic in tack to avoid regression. */
  777. if (compatible[0] != 0) {
  778. if((strstr(compatible, RELOC("python")) == NULL) &&
  779.    (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
  780.    (strstr(compatible, RELOC("Winnipeg")) == NULL))
  781. continue;
  782. } else if (model[0] != 0) {
  783. if ((strstr(model, RELOC("ython")) == NULL) &&
  784.     (strstr(model, RELOC("peedwagon")) == NULL) &&
  785.     (strstr(model, RELOC("innipeg")) == NULL))
  786. continue;
  787. }
  788. if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL)) {
  789. continue;
  790. }
  791. if (call_prom(RELOC("getprop"), 4, 1, node, 
  792.      RELOC("tce-table-minalign"), &minalign, 
  793.      sizeof(minalign)) < 0) {
  794. minalign = 0;
  795. }
  796. if (call_prom(RELOC("getprop"), 4, 1, node, 
  797.      RELOC("tce-table-minsize"), &minsize, 
  798.      sizeof(minsize)) < 0) {
  799. minsize = 4UL << 20;
  800. }
  801. /* Even though we read what OF wants, we just set the table
  802.  * size to 4 MB.  This is enough to map 2GB of PCI DMA space.
  803.  * By doing this, we avoid the pitfalls of trying to DMA to
  804.  * MMIO space and the DMA alias hole.
  805.  */
  806. minsize = 4UL << 20;
  807. /* Align to the greater of the align or size */
  808. align = (minalign < minsize) ? minsize : minalign;
  809. /* Carve out storage for the TCE table. */
  810. base = lmb_alloc(minsize, align);
  811. if ( !base ) {
  812. prom_print(RELOC("ERROR, cannot find space for TCE table.n"));
  813. prom_exit();
  814. }
  815. vbase = absolute_to_virt(base);
  816. /* Save away the TCE table attributes for later use. */
  817. prom_tce_table[table].node = node;
  818. prom_tce_table[table].base = vbase;
  819. prom_tce_table[table].size = minsize;
  820. #ifdef DEBUG_PROM
  821. prom_print(RELOC("TCE table: 0x"));
  822. prom_print_hex(table);
  823. prom_print_nl();
  824. prom_print(RELOC("tnode = 0x"));
  825. prom_print_hex(node);
  826. prom_print_nl();
  827. prom_print(RELOC("tbase = 0x"));
  828. prom_print_hex(vbase);
  829. prom_print_nl();
  830. prom_print(RELOC("tsize = 0x"));
  831. prom_print_hex(minsize);
  832. prom_print_nl();
  833. #endif
  834. /* Initialize the table to have a one-to-one mapping
  835.  * over the allocated size.
  836.  */
  837. tce_entryp = (unsigned long *)base;
  838. for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
  839. tce_entry = (i << PAGE_SHIFT);
  840. tce_entry |= 0x3;
  841. *tce_entryp = tce_entry;
  842. }
  843. /* Call OF to setup the TCE hardware */
  844. if (call_prom(RELOC("package-to-path"), 3, 1, node,
  845.                              path, 255) <= 0) {
  846.                         prom_print(RELOC("package-to-path failedn"));
  847.                 } else {
  848.                         prom_print(RELOC("opened "));
  849.                         prom_print(path);
  850.                         prom_print_nl();
  851.                 }
  852.                 phb_node = (ihandle)call_prom(RELOC("open"), 1, 1, path);
  853.                 if ( (long)phb_node <= 0) {
  854.                         prom_print(RELOC("open failedn"));
  855.                 } else {
  856.                         prom_print(RELOC("open successn"));
  857.                 }
  858.                 call_prom(RELOC("call-method"), 6, 0,
  859.                              RELOC("set-64-bit-addressing"),
  860.      phb_node,
  861.      -1,
  862.                              minsize, 
  863.                              base & 0xffffffff,
  864.                              (base >> 32) & 0xffffffff);
  865.                 call_prom(RELOC("close"), 1, 0, phb_node);
  866. table++;
  867. }
  868. /* Flag the first invalid entry */
  869. prom_tce_table[table].node = 0;
  870. #ifdef DEBUG_PROM
  871. prom_print(RELOC("ending prom_initialize_tce_tablen"));
  872. #endif
  873. }
  874. /*
  875.  * With CHRP SMP we need to use the OF to start the other
  876.  * processors so we can't wait until smp_boot_cpus (the OF is
  877.  * trashed by then) so we have to put the processors into
  878.  * a holding pattern controlled by the kernel (not OF) before
  879.  * we destroy the OF.
  880.  *
  881.  * This uses a chunk of low memory, puts some holding pattern
  882.  * code there and sends the other processors off to there until
  883.  * smp_boot_cpus tells them to do something.  The holding pattern
  884.  * checks that address until its cpu # is there, when it is that
  885.  * cpu jumps to __secondary_start().  smp_boot_cpus() takes care
  886.  * of setting those values.
  887.  *
  888.  * We also use physical address 0x4 here to tell when a cpu
  889.  * is in its holding pattern code.
  890.  *
  891.  * Fixup comment... DRENG / PPPBBB - Peter
  892.  *
  893.  * -- Cort
  894.  */
  895. static void
  896. prom_hold_cpus(unsigned long mem)
  897. {
  898. unsigned long i;
  899. unsigned int reg;
  900. phandle node;
  901. unsigned long offset = reloc_offset();
  902. char type[64], *path;
  903. int cpuid = 0;
  904. extern void __secondary_hold(void);
  905.         extern unsigned long __secondary_hold_spinloop;
  906.         extern unsigned long __secondary_hold_acknowledge;
  907.         unsigned long *spinloop     = __v2a(&__secondary_hold_spinloop);
  908.         unsigned long *acknowledge  = __v2a(&__secondary_hold_acknowledge);
  909.         unsigned long secondary_hold = (unsigned long)__v2a(*PTRRELOC((unsigned long *)__secondary_hold));
  910.         struct naca_struct *_naca = RELOC(naca);
  911. struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
  912. struct prom_t *_prom = PTRRELOC(&prom);
  913. /* Initially, we must have one active CPU. */
  914. _naca->processorCount = 1;
  915. #ifdef DEBUG_PROM
  916. prom_print(RELOC("prom_hold_cpus: start...n"));
  917. prom_print(RELOC("    1) spinloop       = 0x"));
  918. prom_print_hex(spinloop);
  919. prom_print_nl();
  920. prom_print(RELOC("    1) *spinloop      = 0x"));
  921. prom_print_hex(*spinloop);
  922. prom_print_nl();
  923. prom_print(RELOC("    1) acknowledge    = 0x"));
  924. prom_print_hex(acknowledge);
  925. prom_print_nl();
  926. prom_print(RELOC("    1) *acknowledge   = 0x"));
  927. prom_print_hex(*acknowledge);
  928. prom_print_nl();
  929. prom_print(RELOC("    1) secondary_hold = 0x"));
  930. prom_print_hex(secondary_hold);
  931. prom_print_nl();
  932. #endif
  933.         /* Set the common spinloop variable, so all of the secondary cpus
  934.  * will block when they are awakened from their OF spinloop.
  935.  * This must occur for both SMP and non SMP kernels, since OF will
  936.  * be trashed when we move the kernel.
  937.          */
  938.         *spinloop = 0;
  939. #ifdef CONFIG_HMT
  940. for (i=0; i < NR_CPUS; i++) {
  941. RELOC(hmt_thread_data)[i].pir = 0xdeadbeef;
  942. }
  943. #endif
  944. /* look for cpus */
  945. for (node = 0; prom_next_node(&node); ) {
  946. type[0] = 0;
  947. call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
  948.   type, sizeof(type));
  949. if (strcmp(type, RELOC("cpu")) != 0)
  950. continue;
  951. /* Skip non-configured cpus. */
  952. call_prom(RELOC("getprop"), 4, 1, node, RELOC("status"),
  953.   type, sizeof(type));
  954. if (strcmp(type, RELOC("okay")) != 0)
  955. continue;
  956.                 reg = -1;
  957. call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
  958.   &reg, sizeof(reg));
  959. /* Only need to start secondary procs, not ourself. */
  960. if ( reg == _prom->cpu )
  961. continue;
  962. path = (char *) mem;
  963. memset(path, 0, 256);
  964. if ((long) call_prom(RELOC("package-to-path"), 3, 1,
  965.      node, path, 255) < 0)
  966. continue;
  967. cpuid++;
  968. #ifdef DEBUG_PROM
  969. prom_print_nl();
  970. prom_print(RELOC("cpuid        = 0x"));
  971. prom_print_hex(cpuid);
  972. prom_print_nl();
  973. prom_print(RELOC("cpu hw idx   = 0x"));
  974. prom_print_hex(reg);
  975. prom_print_nl();
  976. #endif
  977. _xPaca[cpuid].xHwProcNum = reg;
  978. prom_print(RELOC("starting cpu "));
  979. prom_print(path);
  980. /* Init the acknowledge var which will be reset by
  981.  * the secondary cpu when it awakens from its OF
  982.  * spinloop.
  983.  */
  984. *acknowledge = (unsigned long)-1;
  985. #ifdef DEBUG_PROM
  986. prom_print(RELOC("    3) spinloop       = 0x"));
  987. prom_print_hex(spinloop);
  988. prom_print_nl();
  989. prom_print(RELOC("    3) *spinloop      = 0x"));
  990. prom_print_hex(*spinloop);
  991. prom_print_nl();
  992. prom_print(RELOC("    3) acknowledge    = 0x"));
  993. prom_print_hex(acknowledge);
  994. prom_print_nl();
  995. prom_print(RELOC("    3) *acknowledge   = 0x"));
  996. prom_print_hex(*acknowledge);
  997. prom_print_nl();
  998. prom_print(RELOC("    3) secondary_hold = 0x"));
  999. prom_print_hex(secondary_hold);
  1000. prom_print_nl();
  1001. prom_print(RELOC("    3) cpuid = 0x"));
  1002. prom_print_hex(cpuid);
  1003. prom_print_nl();
  1004. #endif
  1005. call_prom(RELOC("start-cpu"), 3, 0, node, secondary_hold, cpuid);
  1006. prom_print(RELOC("..."));
  1007. for ( i = 0 ; (i < 100000000) && 
  1008.       (*acknowledge == ((unsigned long)-1)); i++ ) ;
  1009. #ifdef DEBUG_PROM
  1010. {
  1011. unsigned long *p = 0x0;
  1012. prom_print(RELOC("    4) 0x0 = 0x"));
  1013. prom_print_hex(*p);
  1014. prom_print_nl();
  1015. }
  1016. #endif
  1017. if (*acknowledge == cpuid) {
  1018. prom_print(RELOC("okn"));
  1019. /* Set the number of active processors. */
  1020. _naca->processorCount++;
  1021. } else {
  1022. prom_print(RELOC("failed: "));
  1023. prom_print_hex(*acknowledge);
  1024. prom_print_nl();
  1025. }
  1026. }
  1027. #ifdef CONFIG_HMT
  1028. /* Only enable HMT on processors that provide support. */
  1029. if (__is_processor(PV_PULSAR) || 
  1030.     __is_processor(PV_ICESTAR) ||
  1031.     __is_processor(PV_SSTAR)) {
  1032. prom_print(RELOC("    starting secondary threadsn"));
  1033. for (i=0; i < _naca->processorCount ;i++) {
  1034. unsigned long threadid = _naca->processorCount*2-1-i;
  1035. if (i == 0) {
  1036. unsigned long pir = _get_PIR();
  1037. if (__is_processor(PV_PULSAR)) {
  1038. RELOC(hmt_thread_data)[i].pir = 
  1039. pir & 0x1f;
  1040. } else {
  1041. RELOC(hmt_thread_data)[i].pir = 
  1042. pir & 0x3ff;
  1043. }
  1044. }
  1045. RELOC(hmt_thread_data)[i].threadid = threadid;
  1046. #ifdef DEBUG_PROM
  1047. prom_print(RELOC("        cpuid 0x"));
  1048. prom_print_hex(i);
  1049. prom_print(RELOC(" maps to threadid 0x"));
  1050. prom_print_hex(threadid);
  1051. prom_print_nl();
  1052. prom_print(RELOC(" pir 0x"));
  1053. prom_print_hex(RELOC(hmt_thread_data)[i].pir);
  1054. prom_print_nl();
  1055. #endif
  1056. _xPaca[threadid].xHwProcNum = _xPaca[i].xHwProcNum+1;
  1057. }
  1058. _naca->processorCount *= 2;
  1059. } else {
  1060. prom_print(RELOC("Processor is not HMT capablen"));
  1061. }
  1062. #endif
  1063. #ifdef DEBUG_PROM
  1064. prom_print(RELOC("prom_hold_cpus: end...n"));
  1065. #endif
  1066. }
  1067. #ifdef CONFIG_PPCDBG
  1068. extern char *trace_names[]; /* defined in udbg.c -- need a better interface */
  1069. static void parse_ppcdbg_optionlist(const char *cmd,
  1070.     const char *cmdend)
  1071. {
  1072. unsigned long offset = reloc_offset();
  1073. char **_trace_names = PTRRELOC(&trace_names[0]);
  1074. const char *all = RELOC("all");
  1075.         struct naca_struct *_naca = RELOC(naca);
  1076. const char *p, *pend;
  1077. int onoff, i, cmdidx;
  1078. unsigned long mask;
  1079. char cmdbuf[30];
  1080. for (p = cmd, pend = strchr(p, ',');
  1081.      p < cmdend;
  1082.      pend = strchr(p, ',')) {
  1083. if (pend == NULL || pend > cmdend)
  1084. pend = cmdend;
  1085. onoff = 1; /* default */
  1086. if (*p == '+' || *p == '-') {
  1087. /* explicit on or off */
  1088. onoff = (*p == '+');
  1089. p++;
  1090. }
  1091. /* parse out p..pend here */
  1092. if (pend - p < sizeof(cmdbuf)) {
  1093. strncpy(cmdbuf, p, pend - p);
  1094. cmdbuf[pend - p] = '';
  1095. for (cmdidx = -1, i = 0; i < PPCDBG_NUM_FLAGS; i++) {
  1096. if (_trace_names[i] &&
  1097.     (strcmp(PTRRELOC(_trace_names[i]), cmdbuf) == 0)) {
  1098. cmdidx = i;
  1099. break;
  1100. }
  1101. }
  1102. mask = 0;
  1103. if (cmdidx >= 0) {
  1104. mask = (1 << cmdidx);
  1105. } else if (strcmp(cmdbuf, all) == 0) {
  1106. mask = PPCDBG_ALL;
  1107. } else {
  1108. prom_print(RELOC("ppcdbg: unknown debug: "));
  1109. prom_print(cmdbuf);
  1110. prom_print_nl();
  1111. }
  1112. if (mask) {
  1113. if (onoff)
  1114. _naca->debug_switch |= mask;
  1115. else
  1116. _naca->debug_switch &= ~mask;
  1117. }
  1118. }
  1119. p = pend+1;
  1120. }
  1121. }
  1122. /*
  1123.  * Parse ppcdbg= cmdline option.
  1124.  *
  1125.  * Option names are listed in <asm/ppcdebug.h> in the trace_names
  1126.  * table.  Multiple names may be listed separated by commas (no whitespace),
  1127.  * and each option may be preceeded by a + or - to force on or off state.
  1128.  * The special option "all" may also be used.  They are processed strictly
  1129.  * left to right.  Multiple ppcdbg= options are the command line are treated
  1130.  * as a single option list.
  1131.  *
  1132.  * Examples:  ppcdbg=phb_init,buswalk
  1133.  *            ppcdbg=all,-mm,-tce
  1134.  *
  1135.  * ToDo: add "group" names that map to common combinations of flags.
  1136.  */
  1137. void parse_ppcdbg_cmd_line(const char *line)
  1138. {
  1139. unsigned long offset = reloc_offset();
  1140. const char *ppcdbgopt = RELOC("ppcdbg=");
  1141. struct naca_struct *_naca = RELOC(naca);
  1142. const char *cmd, *end;
  1143. _naca->debug_switch = PPC_DEBUG_DEFAULT; /* | PPCDBG_BUSWALK | PPCDBG_PHBINIT | PPCDBG_MM | PPCDBG_MMINIT | PPCDBG_TCEINIT | PPCDBG_TCE */
  1144. cmd = line;
  1145. while (cmd && (cmd = strstr(cmd, ppcdbgopt)) != NULL) {
  1146. cmd += 7; /* skip ppcdbg= */
  1147. for (end = cmd;
  1148.      *end != '' && *end != 't' && *end != ' ';
  1149.      end++)
  1150. ; /* scan to whitespace or end */
  1151. parse_ppcdbg_optionlist(cmd, end);
  1152. }
  1153. }
  1154. #endif /* CONFIG_PPCDBG */
  1155. /*
  1156.  * Do minimal cmd_line parsing for early boot options.
  1157.  */
  1158. static void __init
  1159. prom_parse_cmd_line(char *line)
  1160. {
  1161. #ifdef CONFIG_PPCDBG
  1162. parse_ppcdbg_cmd_line(line);
  1163. #endif
  1164. }
  1165. /*
  1166.  * We enter here early on, when the Open Firmware prom is still
  1167.  * handling exceptions and the MMU hash table for us.
  1168.  */
  1169. unsigned long __init
  1170. prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
  1171.   unsigned long r6, unsigned long r7, yaboot_debug_t *yaboot)
  1172. {
  1173. int chrp = 0;
  1174. unsigned long mem;
  1175. ihandle prom_mmu, prom_op, prom_root, prom_cpu;
  1176. phandle cpu_pkg;
  1177. unsigned long offset = reloc_offset();
  1178. long l, sz;
  1179. char *p, *d;
  1180.   unsigned long phys;
  1181.         u32 getprop_rval;
  1182.         struct naca_struct   *_naca = RELOC(naca);
  1183. struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
  1184. struct prom_t *_prom = PTRRELOC(&prom);
  1185. char *_cmd_line = PTRRELOC(&cmd_line[0]);
  1186. /* Default machine type. */
  1187. _naca->platform = PLATFORM_PSERIES;
  1188. /* Reset klimit to take into account the embedded system map */
  1189. if (RELOC(embedded_sysmap_end))
  1190. RELOC(klimit) = __va(PAGE_ALIGN(RELOC(embedded_sysmap_end)));
  1191. /* Get a handle to the prom entry point before anything else */
  1192. _prom->entry = pp;
  1193. _prom->bi_recs = prom_bi_rec_verify((struct bi_record *)r6);
  1194. if ( _prom->bi_recs != NULL ) {
  1195. RELOC(klimit) = PTRUNRELOC((unsigned long)_prom->bi_recs + _prom->bi_recs->data[1]);
  1196. }
  1197. #ifdef DEBUG_YABOOT
  1198. call_yaboot(yaboot->dummy,offset>>32,offset&0xffffffff);
  1199. call_yaboot(yaboot->printf, RELOC("offset = 0x%08x%08xn"), LONG_MSW(offset), LONG_LSW(offset));
  1200. #endif
  1201.   /* Default */
  1202.   phys = KERNELBASE - offset;
  1203. #ifdef DEBUG_YABOOT
  1204. call_yaboot(yaboot->printf, RELOC("phys = 0x%08x%08xn"), LONG_MSW(phys), LONG_LSW(phys));
  1205. #endif
  1206. #ifdef DEBUG_YABOOT
  1207. _prom->yaboot = yaboot;
  1208. call_yaboot(yaboot->printf, RELOC("pp = 0x%08x%08xn"), LONG_MSW(pp), LONG_LSW(pp));
  1209. call_yaboot(yaboot->printf, RELOC("prom = 0x%08x%08xn"), LONG_MSW(_prom->entry), LONG_LSW(_prom->entry));
  1210. #endif
  1211. /* First get a handle for the stdout device */
  1212. _prom->chosen = (ihandle)call_prom(RELOC("finddevice"), 1, 1,
  1213.        RELOC("/chosen"));
  1214. #ifdef DEBUG_YABOOT
  1215. call_yaboot(yaboot->printf, RELOC("prom->chosen = 0x%08x%08xn"), LONG_MSW(_prom->chosen), LONG_LSW(_prom->chosen));
  1216. #endif
  1217. if ((long)_prom->chosen <= 0)
  1218. prom_exit();
  1219.         if ((long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
  1220.     RELOC("stdout"), &getprop_rval,
  1221.     sizeof(getprop_rval)) <= 0)
  1222.                 prom_exit();
  1223.         _prom->stdout = (ihandle)(unsigned long)getprop_rval;
  1224. #ifdef DEBUG_YABOOT
  1225.         if (_prom->stdout == 0) {
  1226.     call_yaboot(yaboot->printf, RELOC("prom->stdout = 0x%08x%08xn"), LONG_MSW(_prom->stdout), LONG_LSW(_prom->stdout));
  1227.         }
  1228. call_yaboot(yaboot->printf, RELOC("prom->stdout = 0x%08x%08xn"), LONG_MSW(_prom->stdout), LONG_LSW(_prom->stdout));
  1229. #endif
  1230. #ifdef DEBUG_YABOOT
  1231. call_yaboot(yaboot->printf, RELOC("Location: 0x11n"));
  1232. #endif
  1233. mem = RELOC(klimit) - offset; 
  1234. #ifdef DEBUG_YABOOT
  1235. call_yaboot(yaboot->printf, RELOC("Location: 0x11bn"));
  1236. #endif
  1237. /* Get the full OF pathname of the stdout device */
  1238. p = (char *) mem;
  1239. memset(p, 0, 256);
  1240. call_prom(RELOC("instance-to-path"), 3, 1, _prom->stdout, p, 255);
  1241. RELOC(of_stdout_device) = PTRUNRELOC(p);
  1242. mem += strlen(p) + 1;
  1243. getprop_rval = 1;
  1244. prom_root = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/"));
  1245. if (prom_root != (ihandle)-1) {
  1246.                 call_prom(RELOC("getprop"), 4, 1,
  1247.                     prom_root, RELOC("#size-cells"),
  1248.     &getprop_rval, sizeof(getprop_rval));
  1249. }
  1250. _prom->encode_phys_size = (getprop_rval==1) ? 32 : 64;
  1251. /* Fetch the cmd_line */
  1252. sz = (long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
  1253.     RELOC("bootargs"), _cmd_line,
  1254.     sizeof(cmd_line)-1);
  1255. if (sz > 0)
  1256. _cmd_line[sz] = '';
  1257. prom_parse_cmd_line(_cmd_line);
  1258. #ifdef DEBUG_PROM
  1259. prom_print(RELOC("DRENG:    Detect OF version...n"));
  1260. #endif
  1261. /* Find the OF version */
  1262. prom_op = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/openprom"));
  1263. if (prom_op != (ihandle)-1) {
  1264. char model[64];
  1265. sz = (long)call_prom(RELOC("getprop"), 4, 1, prom_op,
  1266.     RELOC("model"), model, 64);
  1267. if (sz > 0) {
  1268. char *c;
  1269. /* hack to skip the ibm chrp firmware # */
  1270. if ( strncmp(model,RELOC("IBM"),3) ) {
  1271. for (c = model; *c; c++)
  1272. if (*c >= '0' && *c <= '9') {
  1273. _prom->version = *c - '0';
  1274. break;
  1275. }
  1276. }
  1277. else
  1278. chrp = 1;
  1279. }
  1280. }
  1281. if (_prom->version >= 3)
  1282. prom_print(RELOC("OF Version 3 detected.n"));
  1283. /* Determine which cpu is actually running right _now_ */
  1284.         if ((long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
  1285.     RELOC("cpu"), &getprop_rval,
  1286.     sizeof(getprop_rval)) <= 0)
  1287.                 prom_exit();
  1288. prom_cpu = (ihandle)(unsigned long)getprop_rval;
  1289. cpu_pkg = call_prom(RELOC("instance-to-package"), 1, 1, prom_cpu);
  1290. call_prom(RELOC("getprop"), 4, 1,
  1291. cpu_pkg, RELOC("reg"),
  1292. &getprop_rval, sizeof(getprop_rval));
  1293. _prom->cpu = (int)(unsigned long)getprop_rval;
  1294. _xPaca[0].xHwProcNum = _prom->cpu;
  1295. #ifdef DEBUG_PROM
  1296.    prom_print(RELOC("Booting CPU hw index = 0x"));
  1297.    prom_print_hex(_prom->cpu);
  1298.    prom_print_nl();
  1299. #endif
  1300. /* Get the boot device and translate it to a full OF pathname. */
  1301. p = (char *) mem;
  1302. l = (long) call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
  1303.     RELOC("bootpath"), p, 1<<20);
  1304. if (l > 0) {
  1305. p[l] = 0; /* should already be null-terminated */
  1306. RELOC(bootpath) = PTRUNRELOC(p);
  1307. mem += l + 1;
  1308. d = (char *) mem;
  1309. *d = 0;
  1310. call_prom(RELOC("canon"), 3, 1, p, d, 1<<20);
  1311. RELOC(bootdevice) = PTRUNRELOC(d);
  1312. mem = DOUBLEWORD_ALIGN(mem + strlen(d) + 1);
  1313. }
  1314. mem = prom_initialize_lmb(mem);
  1315. mem = prom_bi_rec_reserve(mem);
  1316. prom_instantiate_rtas();
  1317.         
  1318.         /* Initialize some system info into the Naca early... */
  1319.         mem = prom_initialize_naca(mem);
  1320.         /* If we are on an SMP machine, then we *MUST* do the
  1321.          * following, regardless of whether we have an SMP
  1322.          * kernel or not.
  1323.          */
  1324.         if ( _naca->processorCount > 1 )
  1325.         prom_hold_cpus(mem);
  1326. mem = check_display(mem);
  1327. #ifdef DEBUG_PROM
  1328. prom_print(RELOC("copying OF device tree...n"));
  1329. #endif
  1330. mem = copy_device_tree(mem);
  1331. RELOC(klimit) = mem + offset;
  1332. lmb_reserve(0, __pa(RELOC(klimit)));
  1333. if (_naca->platform == PLATFORM_PSERIES)
  1334. prom_initialize_tce_table();
  1335.   if ((long) call_prom(RELOC("getprop"), 4, 1,
  1336. _prom->chosen,
  1337. RELOC("mmu"),
  1338. &getprop_rval,
  1339. sizeof(getprop_rval)) <= 0) {
  1340. prom_print(RELOC(" no MMU foundn"));
  1341.                 prom_exit();
  1342. }
  1343. /* We assume the phys. address size is 3 cells */
  1344. RELOC(prom_mmu) = (ihandle)(unsigned long)getprop_rval;
  1345. if ((long)call_prom(RELOC("call-method"), 4, 4,
  1346. RELOC("translate"),
  1347. prom_mmu,
  1348. (void *)(KERNELBASE - offset),
  1349. (void *)1) != 0) {
  1350. prom_print(RELOC(" (translate failed) "));
  1351. } else {
  1352. prom_print(RELOC(" (translate ok) "));
  1353. phys = (unsigned long)_prom->args.rets[3];
  1354. }
  1355. /* If OpenFirmware version >= 3, then use quiesce call */
  1356. if (_prom->version >= 3) {
  1357. prom_print(RELOC("Calling quiesce ...n"));
  1358. call_prom(RELOC("quiesce"), 0, 0);
  1359. phys = KERNELBASE - offset;
  1360. }
  1361. prom_print(RELOC("returning from prom_initn"));
  1362. return phys;
  1363. }
  1364. static int
  1365. prom_set_color(ihandle ih, int i, int r, int g, int b)
  1366. {
  1367. unsigned long offset = reloc_offset();
  1368. return (int)(long)call_prom(RELOC("call-method"), 6, 1,
  1369.                     RELOC("color!"),
  1370.                                     ih,
  1371.                                     (void *)(long) i,
  1372.                                     (void *)(long) b,
  1373.                                     (void *)(long) g,
  1374.                                     (void *)(long) r );
  1375. }
  1376. /*
  1377.  * If we have a display that we don't know how to drive,
  1378.  * we will want to try to execute OF's open method for it
  1379.  * later.  However, OF will probably fall over if we do that
  1380.  * we've taken over the MMU.
  1381.  * So we check whether we will need to open the display,
  1382.  * and if so, open it now.
  1383.  */
  1384. static unsigned long __init
  1385. check_display(unsigned long mem)
  1386. {
  1387. phandle node;
  1388. ihandle ih;
  1389. int i;
  1390. unsigned long offset = reloc_offset();
  1391.         struct prom_t *_prom = PTRRELOC(&prom);
  1392. char type[64], *path;
  1393. static unsigned char default_colors[] = {
  1394. 0x00, 0x00, 0x00,
  1395. 0x00, 0x00, 0xaa,
  1396. 0x00, 0xaa, 0x00,
  1397. 0x00, 0xaa, 0xaa,
  1398. 0xaa, 0x00, 0x00,
  1399. 0xaa, 0x00, 0xaa,
  1400. 0xaa, 0xaa, 0x00,
  1401. 0xaa, 0xaa, 0xaa,
  1402. 0x55, 0x55, 0x55,
  1403. 0x55, 0x55, 0xff,
  1404. 0x55, 0xff, 0x55,
  1405. 0x55, 0xff, 0xff,
  1406. 0xff, 0x55, 0x55,
  1407. 0xff, 0x55, 0xff,
  1408. 0xff, 0xff, 0x55,
  1409. 0xff, 0xff, 0xff
  1410. };
  1411. _prom->disp_node = 0;
  1412. for (node = 0; prom_next_node(&node); ) {
  1413. type[0] = 0;
  1414. call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
  1415.   type, sizeof(type));
  1416. if (strcmp(type, RELOC("display")) != 0)
  1417. continue;
  1418. /* It seems OF doesn't null-terminate the path :-( */
  1419. path = (char *) mem;
  1420. memset(path, 0, 256);
  1421. if ((long) call_prom(RELOC("package-to-path"), 3, 1,
  1422.     node, path, 255) < 0)
  1423. continue;
  1424. prom_print(RELOC("opening display "));
  1425. prom_print(path);
  1426. ih = (ihandle)call_prom(RELOC("open"), 1, 1, path);
  1427. if (ih == (ihandle)0 || ih == (ihandle)-1) {
  1428. prom_print(RELOC("... failedn"));
  1429. continue;
  1430. }
  1431. prom_print(RELOC("... okn"));
  1432. if (_prom->disp_node == 0)
  1433. _prom->disp_node = (ihandle)(unsigned long)node;
  1434. /* Setup a useable color table when the appropriate
  1435.  * method is available. Should update this to set-colors */
  1436. for (i = 0; i < 32; i++)
  1437. if (prom_set_color(ih, i, RELOC(default_colors)[i*3],
  1438.    RELOC(default_colors)[i*3+1],
  1439.    RELOC(default_colors)[i*3+2]) != 0)
  1440. break;
  1441. #ifdef CONFIG_FB
  1442. for (i = 0; i < LINUX_LOGO_COLORS; i++)
  1443. if (prom_set_color(ih, i + 32,
  1444.    RELOC(linux_logo_red)[i],
  1445.    RELOC(linux_logo_green)[i],
  1446.    RELOC(linux_logo_blue)[i]) != 0)
  1447. break;
  1448. #endif /* CONFIG_FB */
  1449. /*
  1450.  * If this display is the device that OF is using for stdout,
  1451.  * move it to the front of the list.
  1452.  */
  1453. mem += strlen(path) + 1;
  1454. i = RELOC(prom_num_displays)++;
  1455. if (RELOC(of_stdout_device) != 0 && i > 0
  1456.     && strcmp(PTRRELOC(RELOC(of_stdout_device)), path) == 0) {
  1457. for (; i > 0; --i)
  1458. RELOC(prom_display_paths[i]) = RELOC(prom_display_paths[i-1]);
  1459. }
  1460. RELOC(prom_display_paths[i]) = PTRUNRELOC(path);
  1461. if (RELOC(prom_num_displays) >= FB_MAX)
  1462. break;
  1463. }
  1464. return DOUBLEWORD_ALIGN(mem);
  1465. }
  1466. void
  1467. virt_irq_init(void)
  1468. {
  1469. int i;
  1470. for (i = 0; i < NR_IRQS; i++)
  1471. virt_irq_to_real_map[i] = UNDEFINED_IRQ;
  1472. for (i = 0; i < NR_HW_IRQS; i++)
  1473. real_irq_to_virt_map[i] = UNDEFINED_IRQ;
  1474. }
  1475. /* Create a mapping for a real_irq if it doesn't already exist.
  1476.  * Return the virtual irq as a convenience.
  1477.  */
  1478. unsigned long
  1479. virt_irq_create_mapping(unsigned long real_irq)
  1480. {
  1481. unsigned long virq;
  1482. if (naca->interrupt_controller == IC_OPEN_PIC)
  1483. return real_irq; /* no mapping for openpic (for now) */
  1484. virq = real_irq_to_virt(real_irq);
  1485. if (virq == UNDEFINED_IRQ) {
  1486. /* Assign a virtual IRQ number */
  1487. if (real_irq < NR_IRQS && virt_irq_to_real(real_irq) == UNDEFINED_IRQ) {
  1488. /* A 1-1 mapping will work. */
  1489. virq = real_irq;
  1490. } else {
  1491. while (last_virt_irq < NR_IRQS &&
  1492.        virt_irq_to_real(++last_virt_irq) != UNDEFINED_IRQ)
  1493. /* skip irq's in use */;
  1494. if (last_virt_irq >= NR_IRQS)
  1495. panic("Too many IRQs are required on this system.  NR_IRQS=%dn", NR_IRQS);
  1496. virq = last_virt_irq;
  1497. }
  1498. virt_irq_to_real_map[virq] = real_irq;
  1499. real_irq_to_virt_map[real_irq] = virq;
  1500. }
  1501. return virq;
  1502. }
  1503. static int __init
  1504. prom_next_node(phandle *nodep)
  1505. {
  1506. phandle node;
  1507. unsigned long offset = reloc_offset();
  1508. if ((node = *nodep) != 0
  1509.     && (*nodep = call_prom(RELOC("child"), 1, 1, node)) != 0)
  1510. return 1;
  1511. if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)
  1512. return 1;
  1513. for (;;) {
  1514. if ((node = call_prom(RELOC("parent"), 1, 1, node)) == 0)
  1515. return 0;
  1516. if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)
  1517. return 1;
  1518. }
  1519. }
  1520. /*
  1521.  * Make a copy of the device tree from the PROM.
  1522.  */
  1523. static unsigned long __init
  1524. copy_device_tree(unsigned long mem_start)
  1525. {
  1526. phandle root;
  1527. unsigned long new_start;
  1528. struct device_node **allnextp;
  1529. unsigned long offset = reloc_offset();
  1530. unsigned long mem_end = mem_start + (8<<20);
  1531. root = call_prom(RELOC("peer"), 1, 1, (phandle)0);
  1532. if (root == (phandle)0) {
  1533. prom_print(RELOC("couldn't get device tree rootn"));
  1534. prom_exit();
  1535. }
  1536. allnextp = &RELOC(allnodes);
  1537. mem_start = DOUBLEWORD_ALIGN(mem_start);
  1538. new_start = inspect_node(root, 0, mem_start, mem_end, &allnextp);
  1539. *allnextp = 0;
  1540. return new_start;
  1541. }
  1542. __init
  1543. static unsigned long
  1544. inspect_node(phandle node, struct device_node *dad,
  1545.      unsigned long mem_start, unsigned long mem_end,
  1546.      struct device_node ***allnextpp)
  1547. {
  1548. int l;
  1549. phandle child;
  1550. struct device_node *np;
  1551. struct property *pp, **prev_propp;
  1552. char *prev_name, *namep;
  1553. unsigned char *valp;
  1554. unsigned long offset = reloc_offset();
  1555. np = (struct device_node *) mem_start;
  1556. mem_start += sizeof(struct device_node);
  1557. memset(np, 0, sizeof(*np));
  1558. np->node = node;
  1559. **allnextpp = PTRUNRELOC(np);
  1560. *allnextpp = &np->allnext;
  1561. if (dad != 0) {
  1562. np->parent = PTRUNRELOC(dad);
  1563. /* we temporarily use the `next' field as `last_child'. */
  1564. if (dad->next == 0)
  1565. dad->child = PTRUNRELOC(np);
  1566. else
  1567. dad->next->sibling = PTRUNRELOC(np);
  1568. dad->next = np;
  1569. }
  1570. /* get and store all properties */
  1571. prev_propp = &np->properties;
  1572. prev_name = RELOC("");
  1573. for (;;) {
  1574. pp = (struct property *) mem_start;
  1575. namep = (char *) (pp + 1);
  1576. pp->name = PTRUNRELOC(namep);
  1577. if ((long) call_prom(RELOC("nextprop"), 3, 1, node, prev_name,
  1578.     namep) <= 0)
  1579. break;
  1580. mem_start = DOUBLEWORD_ALIGN((unsigned long)namep + strlen(namep) + 1);
  1581. prev_name = namep;
  1582. valp = (unsigned char *) mem_start;
  1583. pp->value = PTRUNRELOC(valp);
  1584. pp->length = (int)(long)
  1585. call_prom(RELOC("getprop"), 4, 1, node, namep,
  1586.   valp, mem_end - mem_start);
  1587. if (pp->length < 0)
  1588. continue;
  1589. mem_start = DOUBLEWORD_ALIGN(mem_start + pp->length);
  1590. *prev_propp = PTRUNRELOC(pp);
  1591. prev_propp = &pp->next;
  1592. }
  1593. *prev_propp = 0;
  1594. /* get the node's full name */
  1595. l = (long) call_prom(RELOC("package-to-path"), 3, 1, node,
  1596.     (char *) mem_start, mem_end - mem_start);
  1597. if (l >= 0) {
  1598. np->full_name = PTRUNRELOC((char *) mem_start);
  1599. *(char *)(mem_start + l) = 0;
  1600. mem_start = DOUBLEWORD_ALIGN(mem_start + l + 1);
  1601. }
  1602. /* do all our children */
  1603. child = call_prom(RELOC("child"), 1, 1, node);
  1604. while (child != (phandle)0) {
  1605. mem_start = inspect_node(child, np, mem_start, mem_end,
  1606.  allnextpp);
  1607. child = call_prom(RELOC("peer"), 1, 1, child);
  1608. }
  1609. return mem_start;
  1610. }
  1611. /*
  1612.  * finish_device_tree is called once things are running normally
  1613.  * (i.e. with text and data mapped to the address they were linked at).
  1614.  * It traverses the device tree and fills in the name, type,
  1615.  * {n_}addrs and {n_}intrs fields of each node.
  1616.  */
  1617. void __init
  1618. finish_device_tree(void)
  1619. {
  1620. unsigned long mem = klimit;
  1621. virt_irq_init();
  1622. mem = finish_node(allnodes, mem, NULL, 0, 0);
  1623. dev_tree_size = mem - (unsigned long) allnodes;
  1624. mem = _ALIGN(mem, PAGE_SIZE);
  1625. lmb_reserve(__pa(klimit), mem-klimit);
  1626. klimit = mem;
  1627. rtas.dev = find_devices("rtas");
  1628. }
  1629. static unsigned long __init
  1630. finish_node(struct device_node *np, unsigned long mem_start,
  1631.     interpret_func *ifunc, int naddrc, int nsizec)
  1632. {
  1633. struct device_node *child;
  1634. int *ip;
  1635. np->name = get_property(np, "name", 0);
  1636. np->type = get_property(np, "device_type", 0);
  1637. /* get the device addresses and interrupts */
  1638. if (ifunc != NULL) {
  1639.   mem_start = ifunc(np, mem_start, naddrc, nsizec);
  1640. }
  1641. mem_start = finish_node_interrupts(np, mem_start);
  1642. /* Look for #address-cells and #size-cells properties. */
  1643. ip = (int *) get_property(np, "#address-cells", 0);
  1644. if (ip != NULL)
  1645. naddrc = *ip;
  1646. ip = (int *) get_property(np, "#size-cells", 0);
  1647. if (ip != NULL)
  1648. nsizec = *ip;
  1649. /* the f50 sets the name to 'display' and 'compatible' to what we
  1650.  * expect for the name -- Cort
  1651.  */
  1652. ifunc = NULL;
  1653. if (!strcmp(np->name, "display"))
  1654. np->name = get_property(np, "compatible", 0);
  1655. if (!strcmp(np->name, "device-tree") || np->parent == NULL)
  1656. ifunc = interpret_root_props;
  1657. else if (np->type == 0)
  1658. ifunc = NULL;
  1659. else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
  1660. ifunc = interpret_pci_props;
  1661. else if (!strcmp(np->type, "isa"))
  1662. ifunc = interpret_isa_props;
  1663. for (child = np->child; child != NULL; child = child->sibling)
  1664. mem_start = finish_node(child, mem_start, ifunc,
  1665. naddrc, nsizec);
  1666. return mem_start;
  1667. }
  1668. /* This routine walks the interrupt tree for a given device node and gather 
  1669.  * all necessary informations according to the draft interrupt mapping
  1670.  * for CHRP. The current version was only tested on Apple "Core99" machines
  1671.  * and may not handle cascaded controllers correctly.
  1672.  */
  1673. __init
  1674. static unsigned long
  1675. finish_node_interrupts(struct device_node *np, unsigned long mem_start)
  1676. {
  1677. /* Finish this node */
  1678. unsigned int *isizep, *asizep, *interrupts, *map, *map_mask, *reg;
  1679. phandle *parent, map_parent;
  1680. struct device_node *node, *parent_node;
  1681. int l, isize, ipsize, asize, map_size, regpsize;
  1682. /* Currently, we don't look at all nodes with no "interrupts" property */
  1683. interrupts = (unsigned int *)get_property(np, "interrupts", &l);
  1684. if (interrupts == NULL)
  1685. return mem_start;
  1686. ipsize = l>>2;
  1687. reg = (unsigned int *)get_property(np, "reg", &l);
  1688. regpsize = l>>2;
  1689. /* We assume default interrupt cell size is 1 (bugus ?) */
  1690. isize = 1;
  1691. node = np;
  1692. do {
  1693.     /* We adjust the cell size if the current parent contains an #interrupt-cells
  1694.      * property */
  1695.     isizep = (unsigned int *)get_property(node, "#interrupt-cells", &l);
  1696.     if (isizep)
  1697.      isize = *isizep;
  1698.     /* We don't do interrupt cascade (ISA) for now, we stop on the first 
  1699.      * controller found
  1700.      */
  1701.     if (get_property(node, "interrupt-controller", &l)) {
  1702.      int i,j;
  1703.      np->intrs = (struct interrupt_info *) mem_start;
  1704. np->n_intrs = ipsize / isize;
  1705. mem_start += np->n_intrs * sizeof(struct interrupt_info);
  1706. for (i = 0; i < np->n_intrs; ++i) {
  1707.     np->intrs[i].line = openpic_to_irq(virt_irq_create_mapping(*interrupts++));
  1708.     np->intrs[i].sense = 1;
  1709.     if (isize > 1)
  1710.         np->intrs[i].sense = *interrupts++;
  1711.     for (j=2; j<isize; j++)
  1712.      interrupts++;
  1713. }
  1714. return mem_start;
  1715.     }
  1716.     /* We lookup for an interrupt-map. This code can only handle one interrupt
  1717.      * per device in the map. We also don't handle #address-cells in the parent
  1718.      * I skip the pci node itself here, may not be necessary but I don't like it's
  1719.      * reg property.
  1720.      */
  1721.     if (np != node)
  1722.         map = (unsigned int *)get_property(node, "interrupt-map", &l);
  1723.      else
  1724.       map = NULL;
  1725.     if (map && l) {
  1726.      int i, found, temp_isize, temp_asize;
  1727.         map_size = l>>2;
  1728.         map_mask = (unsigned int *)get_property(node, "interrupt-map-mask", &l);
  1729.         asizep = (unsigned int *)get_property(node, "#address-cells", &l);
  1730.         if (asizep && l == sizeof(unsigned int))
  1731.             asize = *asizep;
  1732.         else
  1733.             asize = 0;
  1734.         found = 0;
  1735.         while (map_size>0 && !found) {
  1736.             found = 1;
  1737.             for (i=0; i<asize; i++) {
  1738.              unsigned int mask = map_mask ? map_mask[i] : 0xffffffff;
  1739.              if (!reg || (i>=regpsize) || ((mask & *map) != (mask & reg[i])))
  1740.                 found = 0;
  1741.             map++;
  1742.             map_size--;
  1743.             }
  1744.             for (i=0; i<isize; i++) {
  1745.              unsigned int mask = map_mask ? map_mask[i+asize] : 0xffffffff;
  1746.              if ((mask & *map) != (mask & interrupts[i]))
  1747.                  found = 0;
  1748.              map++;
  1749.              map_size--;
  1750.             }
  1751.             map_parent = *((phandle *)map);
  1752.             map+=1; map_size-=1;
  1753.             parent_node = find_phandle(map_parent);
  1754.             temp_isize = isize;
  1755.     temp_asize = 0;
  1756.             if (parent_node) {
  1757. isizep = (unsigned int *)get_property(parent_node, "#interrupt-cells", &l);
  1758.      if (isizep)
  1759.          temp_isize = *isizep;
  1760. asizep = (unsigned int *)get_property(parent_node, "#address-cells", &l);
  1761. if (asizep && l == sizeof(unsigned int))
  1762. temp_asize = *asizep;
  1763.             }
  1764.             if (!found) {
  1765. map += temp_isize + temp_asize;
  1766. map_size -= temp_isize + temp_asize;
  1767.             }
  1768.         }
  1769.         if (found) {
  1770.     /* Mapped to a new parent.  Use the reg and interrupts specified in
  1771.      * the map as the new search parameters.  Then search from the parent.
  1772.      */
  1773.             node = parent_node;
  1774.     reg = map;
  1775.     regpsize = temp_asize;
  1776.     interrupts = map + temp_asize;
  1777.     ipsize = temp_isize;
  1778.     continue;
  1779.         }
  1780.     }
  1781.     /* We look for an explicit interrupt-parent.
  1782.      */
  1783.     parent = (phandle *)get_property(node, "interrupt-parent", &l);
  1784.     if (parent && (l == sizeof(phandle)) &&
  1785.      (parent_node = find_phandle(*parent))) {
  1786.      node = parent_node;
  1787.      continue;
  1788.     }
  1789.     /* Default, get real parent */
  1790.     node = node->parent;
  1791. } while (node);
  1792. return mem_start;
  1793. }
  1794. int
  1795. prom_n_addr_cells(struct device_node* np)
  1796. {
  1797. int* ip;
  1798. do {
  1799. if (np->parent)
  1800. np = np->parent;
  1801. ip = (int *) get_property(np, "#address-cells", 0);
  1802. if (ip != NULL)
  1803. return *ip;
  1804. } while (np->parent);
  1805. /* No #address-cells property for the root node, default to 1 */
  1806. return 1;
  1807. }
  1808. int
  1809. prom_n_size_cells(struct device_node* np)
  1810. {
  1811. int* ip;
  1812. do {
  1813. if (np->parent)
  1814. np = np->parent;
  1815. ip = (int *) get_property(np, "#size-cells", 0);
  1816. if (ip != NULL)
  1817. return *ip;
  1818. } while (np->parent);
  1819. /* No #size-cells property for the root node, default to 1 */
  1820. return 1;
  1821. }
  1822. static unsigned long __init
  1823. interpret_pci_props(struct device_node *np, unsigned long mem_start,
  1824.     int naddrc, int nsizec)
  1825. {
  1826. struct address_range *adr;
  1827. struct pci_reg_property *pci_addrs;
  1828. int i, l;
  1829. pci_addrs = (struct pci_reg_property *)
  1830. get_property(np, "assigned-addresses", &l);
  1831. if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {
  1832. i = 0;
  1833. adr = (struct address_range *) mem_start;
  1834. while ((l -= sizeof(struct pci_reg_property)) >= 0) {
  1835. adr[i].space = pci_addrs[i].addr.a_hi;
  1836. adr[i].address = pci_addrs[i].addr.a_lo;
  1837. adr[i].size = pci_addrs[i].size_lo;
  1838. ++i;
  1839. }
  1840. np->addrs = adr;
  1841. np->n_addrs = i;
  1842. mem_start += i * sizeof(struct address_range);
  1843. }
  1844. return mem_start;
  1845. }
  1846. static unsigned long __init
  1847. interpret_isa_props(struct device_node *np, unsigned long mem_start,
  1848.     int naddrc, int nsizec)
  1849. {
  1850. struct isa_reg_property *rp;
  1851. struct address_range *adr;
  1852. int i, l;
  1853. rp = (struct isa_reg_property *) get_property(np, "reg", &l);
  1854. if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
  1855. i = 0;
  1856. adr = (struct address_range *) mem_start;
  1857. while ((l -= sizeof(struct reg_property)) >= 0) {
  1858. adr[i].space = rp[i].space;
  1859. adr[i].address = rp[i].address
  1860. + (adr[i].space? 0: _ISA_MEM_BASE);
  1861. adr[i].size = rp[i].size;
  1862. ++i;
  1863. }
  1864. np->addrs = adr;
  1865. np->n_addrs = i;
  1866. mem_start += i * sizeof(struct address_range);
  1867. }
  1868. return mem_start;
  1869. }
  1870. static unsigned long __init
  1871. interpret_root_props(struct device_node *np, unsigned long mem_start,
  1872.      int naddrc, int nsizec)
  1873. {
  1874. struct address_range *adr;
  1875. int i, l;
  1876. unsigned int *rp;
  1877. int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
  1878. rp = (unsigned int *) get_property(np, "reg", &l);
  1879. if (rp != 0 && l >= rpsize) {
  1880. i = 0;
  1881. adr = (struct address_range *) mem_start;
  1882. while ((l -= rpsize) >= 0) {
  1883. adr[i].space = 0;
  1884. adr[i].address = rp[naddrc - 1];
  1885. adr[i].size = rp[naddrc + nsizec - 1];
  1886. ++i;
  1887. rp += naddrc + nsizec;
  1888. }
  1889. np->addrs = adr;
  1890. np->n_addrs = i;
  1891. mem_start += i * sizeof(struct address_range);
  1892. }
  1893. return mem_start;
  1894. }
  1895. /*
  1896.  * Work out the sense (active-low level / active-high edge)
  1897.  * of each interrupt from the device tree.
  1898.  */
  1899. void __init
  1900. prom_get_irq_senses(unsigned char *senses, int off, int max)
  1901. {
  1902. struct device_node *np;
  1903. int i, j;
  1904. /* default to level-triggered */
  1905. memset(senses, 1, max - off);
  1906. for (np = allnodes; np != 0; np = np->allnext) {
  1907. for (j = 0; j < np->n_intrs; j++) {
  1908. i = np->intrs[j].line;
  1909. if (i >= off && i < max)
  1910. senses[i-off] = np->intrs[j].sense;
  1911. }
  1912. }
  1913. }
  1914. /*
  1915.  * Construct and return a list of the device_nodes with a given name.
  1916.  */
  1917. struct device_node *
  1918. find_devices(const char *name)
  1919. {
  1920. struct device_node *head, **prevp, *np;
  1921. prevp = &head;
  1922. for (np = allnodes; np != 0; np = np->allnext) {
  1923. if (np->name != 0 && strcasecmp(np->name, name) == 0) {
  1924. *prevp = np;
  1925. prevp = &np->next;
  1926. }
  1927. }
  1928. *prevp = 0;
  1929. return head;
  1930. }
  1931. /*
  1932.  * Construct and return a list of the device_nodes with a given type.
  1933.  */
  1934. struct device_node *
  1935. find_type_devices(const char *type)
  1936. {
  1937. struct device_node *head, **prevp, *np;
  1938. prevp = &head;
  1939. for (np = allnodes; np != 0; np = np->allnext) {
  1940. if (np->type != 0 && strcasecmp(np->type, type) == 0) {
  1941. *prevp = np;
  1942. prevp = &np->next;
  1943. }
  1944. }
  1945. *prevp = 0;
  1946. return head;
  1947. }
  1948. /*
  1949.  * Returns all nodes linked together
  1950.  */
  1951. struct device_node * __openfirmware
  1952. find_all_nodes(void)
  1953. {
  1954. struct device_node *head, **prevp, *np;
  1955. prevp = &head;
  1956. for (np = allnodes; np != 0; np = np->allnext) {
  1957. *prevp = np;
  1958. prevp = &np->next;
  1959. }
  1960. *prevp = 0;
  1961. return head;
  1962. }
  1963. /* Checks if the given "compat" string matches one of the strings in
  1964.  * the device's "compatible" property
  1965.  */
  1966. int
  1967. device_is_compatible(struct device_node *device, const char *compat)
  1968. {
  1969. const char* cp;
  1970. int cplen, l;
  1971. cp = (char *) get_property(device, "compatible", &cplen);
  1972. if (cp == NULL)
  1973. return 0;
  1974. while (cplen > 0) {
  1975. if (strncasecmp(cp, compat, strlen(compat)) == 0)
  1976. return 1;
  1977. l = strlen(cp) + 1;
  1978. cp += l;
  1979. cplen -= l;
  1980. }
  1981. return 0;
  1982. }
  1983. /*
  1984.  * Indicates whether the root node has a given value in its
  1985.  * compatible property.
  1986.  */
  1987. int
  1988. machine_is_compatible(const char *compat)
  1989. {
  1990. struct device_node *root;
  1991. root = find_path_device("/");
  1992. if (root == 0)
  1993. return 0;
  1994. return device_is_compatible(root, compat);
  1995. }
  1996. /*
  1997.  * Construct and return a list of the device_nodes with a given type
  1998.  * and compatible property.
  1999.  */
  2000. struct device_node *
  2001. find_compatible_devices(const char *type, const char *compat)
  2002. {
  2003. struct device_node *head, **prevp, *np;
  2004. prevp = &head;
  2005. for (np = allnodes; np != 0; np = np->allnext) {
  2006. if (type != NULL
  2007.     && !(np->type != 0 && strcasecmp(np->type, type) == 0))
  2008. continue;
  2009. if (device_is_compatible(np, compat)) {
  2010. *prevp = np;
  2011. prevp = &np->next;
  2012. }
  2013. }
  2014. *prevp = 0;
  2015. return head;
  2016. }
  2017. /*
  2018.  * Find the device_node with a given full_name.
  2019.  */
  2020. struct device_node *
  2021. find_path_device(const char *path)
  2022. {
  2023. struct device_node *np;
  2024. for (np = allnodes; np != 0; np = np->allnext)
  2025. if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
  2026. return np;
  2027. return NULL;
  2028. }
  2029. /*
  2030.  * Find the device_node with a given phandle.
  2031.  */
  2032. static struct device_node * __init
  2033. find_phandle(phandle ph)
  2034. {
  2035. struct device_node *np;
  2036. for (np = allnodes; np != 0; np = np->allnext)
  2037. if (np->node == ph)
  2038. return np;
  2039. return NULL;
  2040. }
  2041. /*
  2042.  * Find a property with a given name for a given node
  2043.  * and return the value.
  2044.  */
  2045. unsigned char *
  2046. get_property(struct device_node *np, const char *name, int *lenp)
  2047. {
  2048. struct property *pp;
  2049. for (pp = np->properties; pp != 0; pp = pp->next)
  2050. if (strcmp(pp->name, name) == 0) {
  2051. if (lenp != 0)
  2052. *lenp = pp->length;
  2053. return pp->value;
  2054. }
  2055. return 0;
  2056. }
  2057. /*
  2058.  * Add a property to a node
  2059.  */
  2060. void __openfirmware
  2061. prom_add_property(struct device_node* np, struct property* prop)
  2062. {
  2063. struct property **next = &np->properties;
  2064. prop->next = NULL;
  2065. while (*next)
  2066. next = &(*next)->next;
  2067. *next = prop;
  2068. }
  2069. #if 0
  2070. void __openfirmware
  2071. print_properties(struct device_node *np)
  2072. {
  2073. struct property *pp;
  2074. char *cp;
  2075. int i, n;
  2076. for (pp = np->properties; pp != 0; pp = pp->next) {
  2077. printk(KERN_INFO "%s", pp->name);
  2078. for (i = strlen(pp->name); i < 16; ++i)
  2079. printk(" ");
  2080. cp = (char *) pp->value;
  2081. for (i = pp->length; i > 0; --i, ++cp)
  2082. if ((i > 1 && (*cp < 0x20 || *cp > 0x7e))
  2083.     || (i == 1 && *cp != 0))
  2084. break;
  2085. if (i == 0 && pp->length > 1) {
  2086. /* looks like a string */
  2087. printk(" %sn", (char *) pp->value);
  2088. } else {
  2089. /* dump it in hex */
  2090. n = pp->length;
  2091. if (n > 64)
  2092. n = 64;
  2093. if (pp->length % 4 == 0) {
  2094. unsigned int *p = (unsigned int *) pp->value;
  2095. n /= 4;
  2096. for (i = 0; i < n; ++i) {
  2097. if (i != 0 && (i % 4) == 0)
  2098. printk("n                ");
  2099. printk(" %08x", *p++);
  2100. }
  2101. } else {
  2102. unsigned char *bp = pp->value;
  2103. for (i = 0; i < n; ++i) {
  2104. if (i != 0 && (i % 16) == 0)
  2105. printk("n                ");
  2106. printk(" %02x", *bp++);
  2107. }
  2108. }
  2109. printk("n");
  2110. if (pp->length > 64)
  2111. printk("                 ... (length = %d)n",
  2112.        pp->length);
  2113. }
  2114. }
  2115. }
  2116. #endif
  2117. void __init
  2118. abort()
  2119. {
  2120. #ifdef CONFIG_XMON
  2121. xmon(NULL);
  2122. #endif
  2123. for (;;)
  2124. prom_exit();
  2125. }
  2126. /* Verify bi_recs are good */
  2127. static struct bi_record *
  2128. prom_bi_rec_verify(struct bi_record *bi_recs)
  2129. {
  2130. struct bi_record *first, *last;
  2131. if ( bi_recs == NULL || bi_recs->tag != BI_FIRST )
  2132. return NULL;
  2133. last = (struct bi_record *)bi_recs->data[0];
  2134. if ( last == NULL || last->tag != BI_LAST )
  2135. return NULL;
  2136. first = (struct bi_record *)last->data[0];
  2137. if ( first == NULL || first != bi_recs )
  2138. return NULL;
  2139. return bi_recs;
  2140. }
  2141. static unsigned long
  2142. prom_bi_rec_reserve(unsigned long mem)
  2143. {
  2144. unsigned long offset = reloc_offset();
  2145. struct prom_t *_prom = PTRRELOC(&prom);
  2146. struct bi_record *rec;
  2147. if ( _prom->bi_recs != NULL) {
  2148. for ( rec=_prom->bi_recs;
  2149.       rec->tag != BI_LAST;
  2150.       rec=bi_rec_next(rec) ) {
  2151. switch (rec->tag) {
  2152. #ifdef CONFIG_BLK_DEV_INITRD
  2153. case BI_INITRD:
  2154. lmb_reserve(rec->data[0], rec->data[1]);
  2155. break;
  2156. #endif /* CONFIG_BLK_DEV_INITRD */
  2157. }
  2158. }
  2159. /* The next use of this field will be after relocation
  2160.    * is enabled, so convert this physical address into a
  2161.    * virtual address.
  2162.    */
  2163. _prom->bi_recs = PTRUNRELOC(_prom->bi_recs);
  2164. }
  2165. return mem;
  2166. }