prom_init.c 26 KB

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