prom_init.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  1. /*
  2. * Note that prom_init() and anything called from prom_init()
  3. * may be running at an address that is different from the address
  4. * that it was linked at. References to static data items are
  5. * handled by compiling this file with -mrelocatable-lib.
  6. */
  7. #include <linux/config.h>
  8. #include <linux/kernel.h>
  9. #include <linux/string.h>
  10. #include <linux/init.h>
  11. #include <linux/threads.h>
  12. #include <linux/spinlock.h>
  13. #include <linux/ioport.h>
  14. #include <linux/pci.h>
  15. #include <linux/slab.h>
  16. #include <linux/bitops.h>
  17. #include <asm/sections.h>
  18. #include <asm/prom.h>
  19. #include <asm/page.h>
  20. #include <asm/irq.h>
  21. #include <asm/io.h>
  22. #include <asm/smp.h>
  23. #include <asm/bootx.h>
  24. #include <asm/system.h>
  25. #include <asm/mmu.h>
  26. #include <asm/pgtable.h>
  27. #include <asm/bootinfo.h>
  28. #include <asm/btext.h>
  29. #include <asm/pci-bridge.h>
  30. #include <asm/open_pic.h>
  31. #include <asm/cacheflush.h>
  32. #ifdef CONFIG_LOGO_LINUX_CLUT224
  33. #include <linux/linux_logo.h>
  34. extern const struct linux_logo logo_linux_clut224;
  35. #endif
  36. /*
  37. * Properties whose value is longer than this get excluded from our
  38. * copy of the device tree. This way we don't waste space storing
  39. * things like "driver,AAPL,MacOS,PowerPC" properties. But this value
  40. * does need to be big enough to ensure that we don't lose things
  41. * like the interrupt-map property on a PCI-PCI bridge.
  42. */
  43. #define MAX_PROPERTY_LENGTH 4096
  44. #ifndef FB_MAX /* avoid pulling in all of the fb stuff */
  45. #define FB_MAX 8
  46. #endif
  47. #define ALIGNUL(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long))
  48. typedef u32 prom_arg_t;
  49. struct prom_args {
  50. const char *service;
  51. int nargs;
  52. int nret;
  53. prom_arg_t args[10];
  54. };
  55. struct pci_address {
  56. unsigned a_hi;
  57. unsigned a_mid;
  58. unsigned a_lo;
  59. };
  60. struct pci_reg_property {
  61. struct pci_address addr;
  62. unsigned size_hi;
  63. unsigned size_lo;
  64. };
  65. struct pci_range {
  66. struct pci_address addr;
  67. unsigned phys;
  68. unsigned size_hi;
  69. unsigned size_lo;
  70. };
  71. struct isa_reg_property {
  72. unsigned space;
  73. unsigned address;
  74. unsigned size;
  75. };
  76. struct pci_intr_map {
  77. struct pci_address addr;
  78. unsigned dunno;
  79. phandle int_ctrler;
  80. unsigned intr;
  81. };
  82. static void prom_exit(void);
  83. static int call_prom(const char *service, int nargs, int nret, ...);
  84. static int call_prom_ret(const char *service, int nargs, int nret,
  85. prom_arg_t *rets, ...);
  86. static void prom_print_hex(unsigned int v);
  87. static int prom_set_color(ihandle ih, int i, int r, int g, int b);
  88. static int prom_next_node(phandle *nodep);
  89. static unsigned long check_display(unsigned long mem);
  90. static void setup_disp_fake_bi(ihandle dp);
  91. static unsigned long copy_device_tree(unsigned long mem_start,
  92. unsigned long mem_end);
  93. static unsigned long inspect_node(phandle node, struct device_node *dad,
  94. unsigned long mem_start, unsigned long mem_end,
  95. struct device_node ***allnextpp);
  96. static void prom_hold_cpus(unsigned long mem);
  97. static void prom_instantiate_rtas(void);
  98. static void * early_get_property(unsigned long base, unsigned long node,
  99. char *prop);
  100. prom_entry prom __initdata;
  101. ihandle prom_chosen __initdata;
  102. ihandle prom_stdout __initdata;
  103. static char *prom_display_paths[FB_MAX] __initdata;
  104. static phandle prom_display_nodes[FB_MAX] __initdata;
  105. static unsigned int prom_num_displays __initdata;
  106. static ihandle prom_disp_node __initdata;
  107. char *of_stdout_device __initdata;
  108. unsigned int rtas_data; /* physical pointer */
  109. unsigned int rtas_entry; /* physical pointer */
  110. unsigned int rtas_size;
  111. unsigned int old_rtas;
  112. boot_infos_t *boot_infos;
  113. char *bootpath;
  114. char *bootdevice;
  115. struct device_node *allnodes;
  116. extern char *klimit;
  117. static void __init
  118. prom_exit(void)
  119. {
  120. struct prom_args args;
  121. args.service = "exit";
  122. args.nargs = 0;
  123. args.nret = 0;
  124. prom(&args);
  125. for (;;) /* should never get here */
  126. ;
  127. }
  128. static int __init
  129. call_prom(const char *service, int nargs, int nret, ...)
  130. {
  131. va_list list;
  132. int i;
  133. struct prom_args prom_args;
  134. prom_args.service = service;
  135. prom_args.nargs = nargs;
  136. prom_args.nret = nret;
  137. va_start(list, nret);
  138. for (i = 0; i < nargs; ++i)
  139. prom_args.args[i] = va_arg(list, prom_arg_t);
  140. va_end(list);
  141. for (i = 0; i < nret; ++i)
  142. prom_args.args[i + nargs] = 0;
  143. prom(&prom_args);
  144. return prom_args.args[nargs];
  145. }
  146. static int __init
  147. call_prom_ret(const char *service, int nargs, int nret, prom_arg_t *rets, ...)
  148. {
  149. va_list list;
  150. int i;
  151. struct prom_args prom_args;
  152. prom_args.service = service;
  153. prom_args.nargs = nargs;
  154. prom_args.nret = nret;
  155. va_start(list, rets);
  156. for (i = 0; i < nargs; ++i)
  157. prom_args.args[i] = va_arg(list, int);
  158. va_end(list);
  159. for (i = 0; i < nret; ++i)
  160. prom_args.args[i + nargs] = 0;
  161. prom(&prom_args);
  162. for (i = 1; i < nret; ++i)
  163. rets[i-1] = prom_args.args[nargs + i];
  164. return prom_args.args[nargs];
  165. }
  166. void __init
  167. prom_print(const char *msg)
  168. {
  169. const char *p, *q;
  170. if (prom_stdout == 0)
  171. return;
  172. for (p = msg; *p != 0; p = q) {
  173. for (q = p; *q != 0 && *q != '\n'; ++q)
  174. ;
  175. if (q > p)
  176. call_prom("write", 3, 1, prom_stdout, p, q - p);
  177. if (*q != 0) {
  178. ++q;
  179. call_prom("write", 3, 1, prom_stdout, "\r\n", 2);
  180. }
  181. }
  182. }
  183. static void __init
  184. prom_print_hex(unsigned int v)
  185. {
  186. char buf[16];
  187. int i, c;
  188. for (i = 0; i < 8; ++i) {
  189. c = (v >> ((7-i)*4)) & 0xf;
  190. c += (c >= 10)? ('a' - 10): '0';
  191. buf[i] = c;
  192. }
  193. buf[i] = ' ';
  194. buf[i+1] = 0;
  195. prom_print(buf);
  196. }
  197. static int __init
  198. prom_set_color(ihandle ih, int i, int r, int g, int b)
  199. {
  200. return call_prom("call-method", 6, 1, "color!", ih, i, b, g, r);
  201. }
  202. static int __init
  203. prom_next_node(phandle *nodep)
  204. {
  205. phandle node;
  206. if ((node = *nodep) != 0
  207. && (*nodep = call_prom("child", 1, 1, node)) != 0)
  208. return 1;
  209. if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
  210. return 1;
  211. for (;;) {
  212. if ((node = call_prom("parent", 1, 1, node)) == 0)
  213. return 0;
  214. if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
  215. return 1;
  216. }
  217. }
  218. #ifdef CONFIG_POWER4
  219. /*
  220. * Set up a hash table with a set of entries in it to map the
  221. * first 64MB of RAM. This is used on 64-bit machines since
  222. * some of them don't have BATs.
  223. */
  224. static inline void make_pte(unsigned long htab, unsigned int hsize,
  225. unsigned int va, unsigned int pa, int mode)
  226. {
  227. unsigned int *pteg;
  228. unsigned int hash, i, vsid;
  229. vsid = ((va >> 28) * 0x111) << 12;
  230. hash = ((va ^ vsid) >> 5) & 0x7fff80;
  231. pteg = (unsigned int *)(htab + (hash & (hsize - 1)));
  232. for (i = 0; i < 8; ++i, pteg += 4) {
  233. if ((pteg[1] & 1) == 0) {
  234. pteg[1] = vsid | ((va >> 16) & 0xf80) | 1;
  235. pteg[3] = pa | mode;
  236. break;
  237. }
  238. }
  239. }
  240. extern unsigned long _SDR1;
  241. extern PTE *Hash;
  242. extern unsigned long Hash_size;
  243. static void __init
  244. prom_alloc_htab(void)
  245. {
  246. unsigned int hsize;
  247. unsigned long htab;
  248. unsigned int addr;
  249. /*
  250. * Because of OF bugs we can't use the "claim" client
  251. * interface to allocate memory for the hash table.
  252. * This code is only used on 64-bit PPCs, and the only
  253. * 64-bit PPCs at the moment are RS/6000s, and their
  254. * OF is based at 0xc00000 (the 12M point), so we just
  255. * arbitrarily use the 0x800000 - 0xc00000 region for the
  256. * hash table.
  257. * -- paulus.
  258. */
  259. hsize = 4 << 20; /* POWER4 has no BATs */
  260. htab = (8 << 20);
  261. call_prom("claim", 3, 1, htab, hsize, 0);
  262. Hash = (void *)(htab + KERNELBASE);
  263. Hash_size = hsize;
  264. _SDR1 = htab + __ilog2(hsize) - 18;
  265. /*
  266. * Put in PTEs for the first 64MB of RAM
  267. */
  268. memset((void *)htab, 0, hsize);
  269. for (addr = 0; addr < 0x4000000; addr += 0x1000)
  270. make_pte(htab, hsize, addr + KERNELBASE, addr,
  271. _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX);
  272. #if 0 /* DEBUG stuff mapping the SCC */
  273. make_pte(htab, hsize, 0x80013000, 0x80013000,
  274. _PAGE_ACCESSED | _PAGE_NO_CACHE | _PAGE_GUARDED | PP_RWXX);
  275. #endif
  276. }
  277. #endif /* CONFIG_POWER4 */
  278. /*
  279. * If we have a display that we don't know how to drive,
  280. * we will want to try to execute OF's open method for it
  281. * later. However, OF will probably fall over if we do that
  282. * we've taken over the MMU.
  283. * So we check whether we will need to open the display,
  284. * and if so, open it now.
  285. */
  286. static unsigned long __init
  287. check_display(unsigned long mem)
  288. {
  289. phandle node;
  290. ihandle ih;
  291. int i, j;
  292. char type[16], *path;
  293. static unsigned char default_colors[] = {
  294. 0x00, 0x00, 0x00,
  295. 0x00, 0x00, 0xaa,
  296. 0x00, 0xaa, 0x00,
  297. 0x00, 0xaa, 0xaa,
  298. 0xaa, 0x00, 0x00,
  299. 0xaa, 0x00, 0xaa,
  300. 0xaa, 0xaa, 0x00,
  301. 0xaa, 0xaa, 0xaa,
  302. 0x55, 0x55, 0x55,
  303. 0x55, 0x55, 0xff,
  304. 0x55, 0xff, 0x55,
  305. 0x55, 0xff, 0xff,
  306. 0xff, 0x55, 0x55,
  307. 0xff, 0x55, 0xff,
  308. 0xff, 0xff, 0x55,
  309. 0xff, 0xff, 0xff
  310. };
  311. const unsigned char *clut;
  312. prom_disp_node = 0;
  313. for (node = 0; prom_next_node(&node); ) {
  314. type[0] = 0;
  315. call_prom("getprop", 4, 1, node, "device_type",
  316. type, sizeof(type));
  317. if (strcmp(type, "display") != 0)
  318. continue;
  319. /* It seems OF doesn't null-terminate the path :-( */
  320. path = (char *) mem;
  321. memset(path, 0, 256);
  322. if (call_prom("package-to-path", 3, 1, node, path, 255) < 0)
  323. continue;
  324. /*
  325. * If this display is the device that OF is using for stdout,
  326. * move it to the front of the list.
  327. */
  328. mem += strlen(path) + 1;
  329. i = prom_num_displays++;
  330. if (of_stdout_device != 0 && i > 0
  331. && strcmp(of_stdout_device, path) == 0) {
  332. for (; i > 0; --i) {
  333. prom_display_paths[i]
  334. = prom_display_paths[i-1];
  335. prom_display_nodes[i]
  336. = prom_display_nodes[i-1];
  337. }
  338. }
  339. prom_display_paths[i] = path;
  340. prom_display_nodes[i] = node;
  341. if (i == 0)
  342. prom_disp_node = node;
  343. if (prom_num_displays >= FB_MAX)
  344. break;
  345. }
  346. for (j=0; j<prom_num_displays; j++) {
  347. path = prom_display_paths[j];
  348. node = prom_display_nodes[j];
  349. prom_print("opening display ");
  350. prom_print(path);
  351. ih = call_prom("open", 1, 1, path);
  352. if (ih == 0 || ih == (ihandle) -1) {
  353. prom_print("... failed\n");
  354. for (i=j+1; i<prom_num_displays; i++) {
  355. prom_display_paths[i-1] = prom_display_paths[i];
  356. prom_display_nodes[i-1] = prom_display_nodes[i];
  357. }
  358. if (--prom_num_displays > 0) {
  359. prom_disp_node = prom_display_nodes[j];
  360. j--;
  361. } else
  362. prom_disp_node = 0;
  363. continue;
  364. } else {
  365. prom_print("... ok\n");
  366. call_prom("setprop", 4, 1, node, "linux,opened", 0, 0);
  367. /*
  368. * Setup a usable color table when the appropriate
  369. * method is available.
  370. * Should update this to use set-colors.
  371. */
  372. clut = default_colors;
  373. for (i = 0; i < 32; i++, clut += 3)
  374. if (prom_set_color(ih, i, clut[0], clut[1],
  375. clut[2]) != 0)
  376. break;
  377. #ifdef CONFIG_LOGO_LINUX_CLUT224
  378. clut = PTRRELOC(logo_linux_clut224.clut);
  379. for (i = 0; i < logo_linux_clut224.clutsize;
  380. i++, clut += 3)
  381. if (prom_set_color(ih, i + 32, clut[0],
  382. clut[1], clut[2]) != 0)
  383. break;
  384. #endif /* CONFIG_LOGO_LINUX_CLUT224 */
  385. }
  386. }
  387. if (prom_stdout) {
  388. phandle p;
  389. p = call_prom("instance-to-package", 1, 1, prom_stdout);
  390. if (p && p != -1) {
  391. type[0] = 0;
  392. call_prom("getprop", 4, 1, p, "device_type",
  393. type, sizeof(type));
  394. if (strcmp(type, "display") == 0)
  395. call_prom("setprop", 4, 1, p, "linux,boot-display",
  396. 0, 0);
  397. }
  398. }
  399. return ALIGNUL(mem);
  400. }
  401. /* This function will enable the early boot text when doing OF booting. This
  402. * way, xmon output should work too
  403. */
  404. static void __init
  405. setup_disp_fake_bi(ihandle dp)
  406. {
  407. #ifdef CONFIG_BOOTX_TEXT
  408. int width = 640, height = 480, depth = 8, pitch;
  409. unsigned address;
  410. struct pci_reg_property addrs[8];
  411. int i, naddrs;
  412. char name[32];
  413. char *getprop = "getprop";
  414. prom_print("Initializing fake screen: ");
  415. memset(name, 0, sizeof(name));
  416. call_prom(getprop, 4, 1, dp, "name", name, sizeof(name));
  417. name[sizeof(name)-1] = 0;
  418. prom_print(name);
  419. prom_print("\n");
  420. call_prom(getprop, 4, 1, dp, "width", &width, sizeof(width));
  421. call_prom(getprop, 4, 1, dp, "height", &height, sizeof(height));
  422. call_prom(getprop, 4, 1, dp, "depth", &depth, sizeof(depth));
  423. pitch = width * ((depth + 7) / 8);
  424. call_prom(getprop, 4, 1, dp, "linebytes",
  425. &pitch, sizeof(pitch));
  426. if (pitch == 1)
  427. pitch = 0x1000; /* for strange IBM display */
  428. address = 0;
  429. call_prom(getprop, 4, 1, dp, "address",
  430. &address, sizeof(address));
  431. if (address == 0) {
  432. /* look for an assigned address with a size of >= 1MB */
  433. naddrs = call_prom(getprop, 4, 1, dp, "assigned-addresses",
  434. addrs, sizeof(addrs));
  435. naddrs /= sizeof(struct pci_reg_property);
  436. for (i = 0; i < naddrs; ++i) {
  437. if (addrs[i].size_lo >= (1 << 20)) {
  438. address = addrs[i].addr.a_lo;
  439. /* use the BE aperture if possible */
  440. if (addrs[i].size_lo >= (16 << 20))
  441. address += (8 << 20);
  442. break;
  443. }
  444. }
  445. if (address == 0) {
  446. prom_print("Failed to get address\n");
  447. return;
  448. }
  449. }
  450. /* kludge for valkyrie */
  451. if (strcmp(name, "valkyrie") == 0)
  452. address += 0x1000;
  453. #ifdef CONFIG_POWER4
  454. #if CONFIG_TASK_SIZE > 0x80000000
  455. #error CONFIG_TASK_SIZE cannot be above 0x80000000 with BOOTX_TEXT on G5
  456. #endif
  457. {
  458. extern boot_infos_t disp_bi;
  459. unsigned long va, pa, i, offset;
  460. va = 0x90000000;
  461. pa = address & 0xfffff000ul;
  462. offset = address & 0x00000fff;
  463. for (i=0; i<0x4000; i++) {
  464. make_pte((unsigned long)Hash - KERNELBASE, Hash_size, va, pa,
  465. _PAGE_ACCESSED | _PAGE_NO_CACHE |
  466. _PAGE_GUARDED | PP_RWXX);
  467. va += 0x1000;
  468. pa += 0x1000;
  469. }
  470. btext_setup_display(width, height, depth, pitch, 0x90000000 | offset);
  471. disp_bi.dispDeviceBase = (u8 *)address;
  472. }
  473. #else /* CONFIG_POWER4 */
  474. btext_setup_display(width, height, depth, pitch, address);
  475. btext_prepare_BAT();
  476. #endif /* CONFIG_POWER4 */
  477. #endif /* CONFIG_BOOTX_TEXT */
  478. }
  479. /*
  480. * Make a copy of the device tree from the PROM.
  481. */
  482. static unsigned long __init
  483. copy_device_tree(unsigned long mem_start, unsigned long mem_end)
  484. {
  485. phandle root;
  486. unsigned long new_start;
  487. struct device_node **allnextp;
  488. root = call_prom("peer", 1, 1, (phandle)0);
  489. if (root == (phandle)0) {
  490. prom_print("couldn't get device tree root\n");
  491. prom_exit();
  492. }
  493. allnextp = &allnodes;
  494. mem_start = ALIGNUL(mem_start);
  495. new_start = inspect_node(root, NULL, mem_start, mem_end, &allnextp);
  496. *allnextp = NULL;
  497. return new_start;
  498. }
  499. static unsigned long __init
  500. inspect_node(phandle node, struct device_node *dad,
  501. unsigned long mem_start, unsigned long mem_end,
  502. struct device_node ***allnextpp)
  503. {
  504. int l;
  505. phandle child;
  506. struct device_node *np;
  507. struct property *pp, **prev_propp;
  508. char *prev_name, *namep;
  509. unsigned char *valp;
  510. np = (struct device_node *) mem_start;
  511. mem_start += sizeof(struct device_node);
  512. memset(np, 0, sizeof(*np));
  513. np->node = node;
  514. **allnextpp = PTRUNRELOC(np);
  515. *allnextpp = &np->allnext;
  516. if (dad != 0) {
  517. np->parent = PTRUNRELOC(dad);
  518. /* we temporarily use the `next' field as `last_child'. */
  519. if (dad->next == 0)
  520. dad->child = PTRUNRELOC(np);
  521. else
  522. dad->next->sibling = PTRUNRELOC(np);
  523. dad->next = np;
  524. }
  525. /* get and store all properties */
  526. prev_propp = &np->properties;
  527. prev_name = "";
  528. for (;;) {
  529. pp = (struct property *) mem_start;
  530. namep = (char *) (pp + 1);
  531. pp->name = PTRUNRELOC(namep);
  532. if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0)
  533. break;
  534. mem_start = ALIGNUL((unsigned long)namep + strlen(namep) + 1);
  535. prev_name = namep;
  536. valp = (unsigned char *) mem_start;
  537. pp->value = PTRUNRELOC(valp);
  538. pp->length = call_prom("getprop", 4, 1, node, namep,
  539. valp, mem_end - mem_start);
  540. if (pp->length < 0)
  541. continue;
  542. #ifdef MAX_PROPERTY_LENGTH
  543. if (pp->length > MAX_PROPERTY_LENGTH)
  544. continue; /* ignore this property */
  545. #endif
  546. mem_start = ALIGNUL(mem_start + pp->length);
  547. *prev_propp = PTRUNRELOC(pp);
  548. prev_propp = &pp->next;
  549. }
  550. if (np->node != 0) {
  551. /* Add a "linux,phandle" property" */
  552. pp = (struct property *) mem_start;
  553. *prev_propp = PTRUNRELOC(pp);
  554. prev_propp = &pp->next;
  555. namep = (char *) (pp + 1);
  556. pp->name = PTRUNRELOC(namep);
  557. strcpy(namep, "linux,phandle");
  558. mem_start = ALIGNUL((unsigned long)namep + strlen(namep) + 1);
  559. pp->value = (unsigned char *) PTRUNRELOC(&np->node);
  560. pp->length = sizeof(np->node);
  561. }
  562. *prev_propp = NULL;
  563. /* get the node's full name */
  564. l = call_prom("package-to-path", 3, 1, node,
  565. mem_start, mem_end - mem_start);
  566. if (l >= 0) {
  567. char *p, *ep;
  568. np->full_name = PTRUNRELOC((char *) mem_start);
  569. *(char *)(mem_start + l) = 0;
  570. /* Fixup an Apple bug where they have bogus \0 chars in the
  571. * middle of the path in some properties
  572. */
  573. for (p = (char *)mem_start, ep = p + l; p < ep; p++)
  574. if ((*p) == '\0') {
  575. memmove(p, p+1, ep - p);
  576. ep--;
  577. }
  578. mem_start = ALIGNUL(mem_start + l + 1);
  579. }
  580. /* do all our children */
  581. child = call_prom("child", 1, 1, node);
  582. while (child != 0) {
  583. mem_start = inspect_node(child, np, mem_start, mem_end,
  584. allnextpp);
  585. child = call_prom("peer", 1, 1, child);
  586. }
  587. return mem_start;
  588. }
  589. unsigned long smp_chrp_cpu_nr __initdata = 0;
  590. /*
  591. * With CHRP SMP we need to use the OF to start the other
  592. * processors so we can't wait until smp_boot_cpus (the OF is
  593. * trashed by then) so we have to put the processors into
  594. * a holding pattern controlled by the kernel (not OF) before
  595. * we destroy the OF.
  596. *
  597. * This uses a chunk of high memory, puts some holding pattern
  598. * code there and sends the other processors off to there until
  599. * smp_boot_cpus tells them to do something. We do that by using
  600. * physical address 0x0. The holding pattern checks that address
  601. * until its cpu # is there, when it is that cpu jumps to
  602. * __secondary_start(). smp_boot_cpus() takes care of setting those
  603. * values.
  604. *
  605. * We also use physical address 0x4 here to tell when a cpu
  606. * is in its holding pattern code.
  607. *
  608. * -- Cort
  609. *
  610. * Note that we have to do this if we have more than one CPU,
  611. * even if this is a UP kernel. Otherwise when we trash OF
  612. * the other CPUs will start executing some random instructions
  613. * and crash the system. -- paulus
  614. */
  615. static void __init
  616. prom_hold_cpus(unsigned long mem)
  617. {
  618. extern void __secondary_hold(void);
  619. unsigned long i;
  620. int cpu;
  621. phandle node;
  622. char type[16], *path;
  623. unsigned int reg;
  624. /*
  625. * XXX: hack to make sure we're chrp, assume that if we're
  626. * chrp we have a device_type property -- Cort
  627. */
  628. node = call_prom("finddevice", 1, 1, "/");
  629. if (call_prom("getprop", 4, 1, node,
  630. "device_type", type, sizeof(type)) <= 0)
  631. return;
  632. /* copy the holding pattern code to someplace safe (0) */
  633. /* the holding pattern is now within the first 0x100
  634. bytes of the kernel image -- paulus */
  635. memcpy((void *)0, _stext, 0x100);
  636. flush_icache_range(0, 0x100);
  637. /* look for cpus */
  638. *(unsigned long *)(0x0) = 0;
  639. asm volatile("dcbf 0,%0": : "r" (0) : "memory");
  640. for (node = 0; prom_next_node(&node); ) {
  641. type[0] = 0;
  642. call_prom("getprop", 4, 1, node, "device_type",
  643. type, sizeof(type));
  644. if (strcmp(type, "cpu") != 0)
  645. continue;
  646. path = (char *) mem;
  647. memset(path, 0, 256);
  648. if (call_prom("package-to-path", 3, 1, node, path, 255) < 0)
  649. continue;
  650. reg = -1;
  651. call_prom("getprop", 4, 1, node, "reg", &reg, sizeof(reg));
  652. cpu = smp_chrp_cpu_nr++;
  653. #ifdef CONFIG_SMP
  654. smp_hw_index[cpu] = reg;
  655. #endif /* CONFIG_SMP */
  656. /* XXX: hack - don't start cpu 0, this cpu -- Cort */
  657. if (cpu == 0)
  658. continue;
  659. prom_print("starting cpu ");
  660. prom_print(path);
  661. *(ulong *)(0x4) = 0;
  662. call_prom("start-cpu", 3, 0, node,
  663. (char *)__secondary_hold - _stext, cpu);
  664. prom_print("...");
  665. for ( i = 0 ; (i < 10000) && (*(ulong *)(0x4) == 0); i++ )
  666. ;
  667. if (*(ulong *)(0x4) == cpu)
  668. prom_print("ok\n");
  669. else {
  670. prom_print("failed: ");
  671. prom_print_hex(*(ulong *)0x4);
  672. prom_print("\n");
  673. }
  674. }
  675. }
  676. static void __init
  677. prom_instantiate_rtas(void)
  678. {
  679. ihandle prom_rtas;
  680. prom_arg_t result;
  681. prom_rtas = call_prom("finddevice", 1, 1, "/rtas");
  682. if (prom_rtas == -1)
  683. return;
  684. rtas_size = 0;
  685. call_prom("getprop", 4, 1, prom_rtas,
  686. "rtas-size", &rtas_size, sizeof(rtas_size));
  687. prom_print("instantiating rtas");
  688. if (rtas_size == 0) {
  689. rtas_data = 0;
  690. } else {
  691. /*
  692. * Ask OF for some space for RTAS.
  693. * Actually OF has bugs so we just arbitrarily
  694. * use memory at the 6MB point.
  695. */
  696. rtas_data = 6 << 20;
  697. prom_print(" at ");
  698. prom_print_hex(rtas_data);
  699. }
  700. prom_rtas = call_prom("open", 1, 1, "/rtas");
  701. prom_print("...");
  702. rtas_entry = 0;
  703. if (call_prom_ret("call-method", 3, 2, &result,
  704. "instantiate-rtas", prom_rtas, rtas_data) == 0)
  705. rtas_entry = result;
  706. if ((rtas_entry == -1) || (rtas_entry == 0))
  707. prom_print(" failed\n");
  708. else
  709. prom_print(" done\n");
  710. }
  711. /*
  712. * We enter here early on, when the Open Firmware prom is still
  713. * handling exceptions and the MMU hash table for us.
  714. */
  715. unsigned long __init
  716. prom_init(int r3, int r4, prom_entry pp)
  717. {
  718. unsigned long mem;
  719. ihandle prom_mmu;
  720. unsigned long offset = reloc_offset();
  721. int i, l;
  722. char *p, *d;
  723. unsigned long phys;
  724. prom_arg_t result[3];
  725. char model[32];
  726. phandle node;
  727. int rc;
  728. /* Default */
  729. phys = (unsigned long) &_stext;
  730. /* First get a handle for the stdout device */
  731. prom = pp;
  732. prom_chosen = call_prom("finddevice", 1, 1, "/chosen");
  733. if (prom_chosen == -1)
  734. prom_exit();
  735. if (call_prom("getprop", 4, 1, prom_chosen, "stdout",
  736. &prom_stdout, sizeof(prom_stdout)) <= 0)
  737. prom_exit();
  738. /* Get the full OF pathname of the stdout device */
  739. mem = (unsigned long) klimit + offset;
  740. p = (char *) mem;
  741. memset(p, 0, 256);
  742. call_prom("instance-to-path", 3, 1, prom_stdout, p, 255);
  743. of_stdout_device = p;
  744. mem += strlen(p) + 1;
  745. /* Get the boot device and translate it to a full OF pathname. */
  746. p = (char *) mem;
  747. l = call_prom("getprop", 4, 1, prom_chosen, "bootpath", p, 1<<20);
  748. if (l > 0) {
  749. p[l] = 0; /* should already be null-terminated */
  750. bootpath = PTRUNRELOC(p);
  751. mem += l + 1;
  752. d = (char *) mem;
  753. *d = 0;
  754. call_prom("canon", 3, 1, p, d, 1<<20);
  755. bootdevice = PTRUNRELOC(d);
  756. mem = ALIGNUL(mem + strlen(d) + 1);
  757. }
  758. prom_instantiate_rtas();
  759. #ifdef CONFIG_POWER4
  760. /*
  761. * Find out how much memory we have and allocate a
  762. * suitably-sized hash table.
  763. */
  764. prom_alloc_htab();
  765. #endif
  766. mem = check_display(mem);
  767. prom_print("copying OF device tree...");
  768. mem = copy_device_tree(mem, mem + (1<<20));
  769. prom_print("done\n");
  770. prom_hold_cpus(mem);
  771. klimit = (char *) (mem - offset);
  772. node = call_prom("finddevice", 1, 1, "/");
  773. rc = call_prom("getprop", 4, 1, node, "model", model, sizeof(model));
  774. if (rc > 0 && !strncmp (model, "Pegasos", 7)
  775. && strncmp (model, "Pegasos2", 8)) {
  776. /* Pegasos 1 has a broken translate method in the OF,
  777. * and furthermore the BATs are mapped 1:1 so the phys
  778. * address calculated above is correct, so let's use
  779. * it directly.
  780. */
  781. } else if (offset == 0) {
  782. /* If we are already running at 0xc0000000, we assume we were
  783. * loaded by an OF bootloader which did set a BAT for us.
  784. * This breaks OF translate so we force phys to be 0.
  785. */
  786. prom_print("(already at 0xc0000000) phys=0\n");
  787. phys = 0;
  788. } else if (call_prom("getprop", 4, 1, prom_chosen, "mmu",
  789. &prom_mmu, sizeof(prom_mmu)) <= 0) {
  790. prom_print(" no MMU found\n");
  791. } else if (call_prom_ret("call-method", 4, 4, result, "translate",
  792. prom_mmu, &_stext, 1) != 0) {
  793. prom_print(" (translate failed)\n");
  794. } else {
  795. /* We assume the phys. address size is 3 cells */
  796. phys = result[2];
  797. }
  798. if (prom_disp_node != 0)
  799. setup_disp_fake_bi(prom_disp_node);
  800. /* Use quiesce call to get OF to shut down any devices it's using */
  801. prom_print("Calling quiesce ...\n");
  802. call_prom("quiesce", 0, 0);
  803. /* Relocate various pointers which will be used once the
  804. kernel is running at the address it was linked at. */
  805. for (i = 0; i < prom_num_displays; ++i)
  806. prom_display_paths[i] = PTRUNRELOC(prom_display_paths[i]);
  807. #ifdef CONFIG_SERIAL_CORE_CONSOLE
  808. /* Relocate the of stdout for console autodetection */
  809. of_stdout_device = PTRUNRELOC(of_stdout_device);
  810. #endif
  811. prom_print("returning 0x");
  812. prom_print_hex(phys);
  813. prom_print("from prom_init\n");
  814. prom_stdout = 0;
  815. return phys;
  816. }
  817. /*
  818. * early_get_property is used to access the device tree image prepared
  819. * by BootX very early on, before the pointers in it have been relocated.
  820. */
  821. static void * __init
  822. early_get_property(unsigned long base, unsigned long node, char *prop)
  823. {
  824. struct device_node *np = (struct device_node *)(base + node);
  825. struct property *pp;
  826. for (pp = np->properties; pp != 0; pp = pp->next) {
  827. pp = (struct property *) (base + (unsigned long)pp);
  828. if (strcmp((char *)((unsigned long)pp->name + base),
  829. prop) == 0) {
  830. return (void *)((unsigned long)pp->value + base);
  831. }
  832. }
  833. return NULL;
  834. }
  835. /* Is boot-info compatible ? */
  836. #define BOOT_INFO_IS_COMPATIBLE(bi) ((bi)->compatible_version <= BOOT_INFO_VERSION)
  837. #define BOOT_INFO_IS_V2_COMPATIBLE(bi) ((bi)->version >= 2)
  838. #define BOOT_INFO_IS_V4_COMPATIBLE(bi) ((bi)->version >= 4)
  839. void __init
  840. bootx_init(unsigned long r4, unsigned long phys)
  841. {
  842. boot_infos_t *bi = (boot_infos_t *) r4;
  843. unsigned long space;
  844. unsigned long ptr, x;
  845. char *model;
  846. boot_infos = PTRUNRELOC(bi);
  847. if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
  848. bi->logicalDisplayBase = NULL;
  849. #ifdef CONFIG_BOOTX_TEXT
  850. btext_init(bi);
  851. /*
  852. * Test if boot-info is compatible. Done only in config
  853. * CONFIG_BOOTX_TEXT since there is nothing much we can do
  854. * with an incompatible version, except display a message
  855. * and eventually hang the processor...
  856. *
  857. * I'll try to keep enough of boot-info compatible in the
  858. * future to always allow display of this message;
  859. */
  860. if (!BOOT_INFO_IS_COMPATIBLE(bi)) {
  861. btext_drawstring(" !!! WARNING - Incompatible version of BootX !!!\n\n\n");
  862. btext_flushscreen();
  863. }
  864. #endif /* CONFIG_BOOTX_TEXT */
  865. /* New BootX enters kernel with MMU off, i/os are not allowed
  866. here. This hack will have been done by the boostrap anyway.
  867. */
  868. if (bi->version < 4) {
  869. /*
  870. * XXX If this is an iMac, turn off the USB controller.
  871. */
  872. model = (char *) early_get_property
  873. (r4 + bi->deviceTreeOffset, 4, "model");
  874. if (model
  875. && (strcmp(model, "iMac,1") == 0
  876. || strcmp(model, "PowerMac1,1") == 0)) {
  877. out_le32((unsigned *)0x80880008, 1); /* XXX */
  878. }
  879. }
  880. /* Move klimit to enclose device tree, args, ramdisk, etc... */
  881. if (bi->version < 5) {
  882. space = bi->deviceTreeOffset + bi->deviceTreeSize;
  883. if (bi->ramDisk)
  884. space = bi->ramDisk + bi->ramDiskSize;
  885. } else
  886. space = bi->totalParamsSize;
  887. klimit = PTRUNRELOC((char *) bi + space);
  888. /* New BootX will have flushed all TLBs and enters kernel with
  889. MMU switched OFF, so this should not be useful anymore.
  890. */
  891. if (bi->version < 4) {
  892. /*
  893. * Touch each page to make sure the PTEs for them
  894. * are in the hash table - the aim is to try to avoid
  895. * getting DSI exceptions while copying the kernel image.
  896. */
  897. for (ptr = ((unsigned long) &_stext) & PAGE_MASK;
  898. ptr < (unsigned long)bi + space; ptr += PAGE_SIZE)
  899. x = *(volatile unsigned long *)ptr;
  900. }
  901. #ifdef CONFIG_BOOTX_TEXT
  902. /*
  903. * Note that after we call btext_prepare_BAT, we can't do
  904. * prom_draw*, flushscreen or clearscreen until we turn the MMU
  905. * on, since btext_prepare_BAT sets disp_bi.logicalDisplayBase
  906. * to a virtual address.
  907. */
  908. btext_prepare_BAT();
  909. #endif
  910. }