prom.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447
  1. /*
  2. * Procedures for interfacing to the Open Firmware PROM on
  3. * Power Macintosh computers.
  4. *
  5. * In particular, we are interested in the device tree
  6. * and in using some of its services (exit, write to stdout).
  7. *
  8. * Paul Mackerras August 1996.
  9. * Copyright (C) 1996 Paul Mackerras.
  10. */
  11. #include <stdarg.h>
  12. #include <linux/config.h>
  13. #include <linux/kernel.h>
  14. #include <linux/string.h>
  15. #include <linux/init.h>
  16. #include <linux/version.h>
  17. #include <linux/threads.h>
  18. #include <linux/spinlock.h>
  19. #include <linux/ioport.h>
  20. #include <linux/pci.h>
  21. #include <linux/slab.h>
  22. #include <linux/bitops.h>
  23. #include <asm/sections.h>
  24. #include <asm/prom.h>
  25. #include <asm/page.h>
  26. #include <asm/processor.h>
  27. #include <asm/irq.h>
  28. #include <asm/io.h>
  29. #include <asm/smp.h>
  30. #include <asm/bootx.h>
  31. #include <asm/system.h>
  32. #include <asm/mmu.h>
  33. #include <asm/pgtable.h>
  34. #include <asm/bootinfo.h>
  35. #include <asm/btext.h>
  36. #include <asm/pci-bridge.h>
  37. #include <asm/open_pic.h>
  38. struct pci_address {
  39. unsigned a_hi;
  40. unsigned a_mid;
  41. unsigned a_lo;
  42. };
  43. struct pci_reg_property {
  44. struct pci_address addr;
  45. unsigned size_hi;
  46. unsigned size_lo;
  47. };
  48. struct isa_reg_property {
  49. unsigned space;
  50. unsigned address;
  51. unsigned size;
  52. };
  53. typedef unsigned long interpret_func(struct device_node *, unsigned long,
  54. int, int);
  55. static interpret_func interpret_pci_props;
  56. static interpret_func interpret_dbdma_props;
  57. static interpret_func interpret_isa_props;
  58. static interpret_func interpret_macio_props;
  59. static interpret_func interpret_root_props;
  60. extern char *klimit;
  61. /* Set for a newworld or CHRP machine */
  62. int use_of_interrupt_tree;
  63. struct device_node *dflt_interrupt_controller;
  64. int num_interrupt_controllers;
  65. int pmac_newworld;
  66. extern unsigned int rtas_entry; /* physical pointer */
  67. extern struct device_node *allnodes;
  68. static unsigned long finish_node(struct device_node *, unsigned long,
  69. interpret_func *, int, int);
  70. static unsigned long finish_node_interrupts(struct device_node *, unsigned long);
  71. static struct device_node *find_phandle(phandle);
  72. extern void enter_rtas(void *);
  73. void phys_call_rtas(int, int, int, ...);
  74. extern char cmd_line[512]; /* XXX */
  75. extern boot_infos_t *boot_infos;
  76. unsigned long dev_tree_size;
  77. void __openfirmware
  78. phys_call_rtas(int service, int nargs, int nret, ...)
  79. {
  80. va_list list;
  81. union {
  82. unsigned long words[16];
  83. double align;
  84. } u;
  85. void (*rtas)(void *, unsigned long);
  86. int i;
  87. u.words[0] = service;
  88. u.words[1] = nargs;
  89. u.words[2] = nret;
  90. va_start(list, nret);
  91. for (i = 0; i < nargs; ++i)
  92. u.words[i+3] = va_arg(list, unsigned long);
  93. va_end(list);
  94. rtas = (void (*)(void *, unsigned long)) rtas_entry;
  95. rtas(&u, rtas_data);
  96. }
  97. /*
  98. * finish_device_tree is called once things are running normally
  99. * (i.e. with text and data mapped to the address they were linked at).
  100. * It traverses the device tree and fills in the name, type,
  101. * {n_}addrs and {n_}intrs fields of each node.
  102. */
  103. void __init
  104. finish_device_tree(void)
  105. {
  106. unsigned long mem = (unsigned long) klimit;
  107. struct device_node *np;
  108. /* All newworld pmac machines and CHRPs now use the interrupt tree */
  109. for (np = allnodes; np != NULL; np = np->allnext) {
  110. if (get_property(np, "interrupt-parent", NULL)) {
  111. use_of_interrupt_tree = 1;
  112. break;
  113. }
  114. }
  115. if (_machine == _MACH_Pmac && use_of_interrupt_tree)
  116. pmac_newworld = 1;
  117. #ifdef CONFIG_BOOTX_TEXT
  118. if (boot_infos && pmac_newworld) {
  119. prom_print("WARNING ! BootX/miBoot booting is not supported on this machine\n");
  120. prom_print(" You should use an Open Firmware bootloader\n");
  121. }
  122. #endif /* CONFIG_BOOTX_TEXT */
  123. if (use_of_interrupt_tree) {
  124. /*
  125. * We want to find out here how many interrupt-controller
  126. * nodes there are, and if we are booted from BootX,
  127. * we need a pointer to the first (and hopefully only)
  128. * such node. But we can't use find_devices here since
  129. * np->name has not been set yet. -- paulus
  130. */
  131. int n = 0;
  132. char *name, *ic;
  133. int iclen;
  134. for (np = allnodes; np != NULL; np = np->allnext) {
  135. ic = get_property(np, "interrupt-controller", &iclen);
  136. name = get_property(np, "name", NULL);
  137. /* checking iclen makes sure we don't get a false
  138. match on /chosen.interrupt_controller */
  139. if ((name != NULL
  140. && strcmp(name, "interrupt-controller") == 0)
  141. || (ic != NULL && iclen == 0 && strcmp(name, "AppleKiwi"))) {
  142. if (n == 0)
  143. dflt_interrupt_controller = np;
  144. ++n;
  145. }
  146. }
  147. num_interrupt_controllers = n;
  148. }
  149. mem = finish_node(allnodes, mem, NULL, 1, 1);
  150. dev_tree_size = mem - (unsigned long) allnodes;
  151. klimit = (char *) mem;
  152. }
  153. static unsigned long __init
  154. finish_node(struct device_node *np, unsigned long mem_start,
  155. interpret_func *ifunc, int naddrc, int nsizec)
  156. {
  157. struct device_node *child;
  158. int *ip;
  159. np->name = get_property(np, "name", NULL);
  160. np->type = get_property(np, "device_type", NULL);
  161. if (!np->name)
  162. np->name = "<NULL>";
  163. if (!np->type)
  164. np->type = "<NULL>";
  165. /* get the device addresses and interrupts */
  166. if (ifunc != NULL)
  167. mem_start = ifunc(np, mem_start, naddrc, nsizec);
  168. if (use_of_interrupt_tree)
  169. mem_start = finish_node_interrupts(np, mem_start);
  170. /* Look for #address-cells and #size-cells properties. */
  171. ip = (int *) get_property(np, "#address-cells", NULL);
  172. if (ip != NULL)
  173. naddrc = *ip;
  174. ip = (int *) get_property(np, "#size-cells", NULL);
  175. if (ip != NULL)
  176. nsizec = *ip;
  177. if (np->parent == NULL)
  178. ifunc = interpret_root_props;
  179. else if (np->type == 0)
  180. ifunc = NULL;
  181. else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
  182. ifunc = interpret_pci_props;
  183. else if (!strcmp(np->type, "dbdma"))
  184. ifunc = interpret_dbdma_props;
  185. else if (!strcmp(np->type, "mac-io")
  186. || ifunc == interpret_macio_props)
  187. ifunc = interpret_macio_props;
  188. else if (!strcmp(np->type, "isa"))
  189. ifunc = interpret_isa_props;
  190. else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
  191. ifunc = interpret_root_props;
  192. else if (!((ifunc == interpret_dbdma_props
  193. || ifunc == interpret_macio_props)
  194. && (!strcmp(np->type, "escc")
  195. || !strcmp(np->type, "media-bay"))))
  196. ifunc = NULL;
  197. /* if we were booted from BootX, convert the full name */
  198. if (boot_infos
  199. && strncmp(np->full_name, "Devices:device-tree", 19) == 0) {
  200. if (np->full_name[19] == 0) {
  201. strcpy(np->full_name, "/");
  202. } else if (np->full_name[19] == ':') {
  203. char *p = np->full_name + 19;
  204. np->full_name = p;
  205. for (; *p; ++p)
  206. if (*p == ':')
  207. *p = '/';
  208. }
  209. }
  210. for (child = np->child; child != NULL; child = child->sibling)
  211. mem_start = finish_node(child, mem_start, ifunc,
  212. naddrc, nsizec);
  213. return mem_start;
  214. }
  215. /*
  216. * Find the interrupt parent of a node.
  217. */
  218. static struct device_node * __init
  219. intr_parent(struct device_node *p)
  220. {
  221. phandle *parp;
  222. parp = (phandle *) get_property(p, "interrupt-parent", NULL);
  223. if (parp == NULL)
  224. return p->parent;
  225. p = find_phandle(*parp);
  226. if (p != NULL)
  227. return p;
  228. /*
  229. * On a powermac booted with BootX, we don't get to know the
  230. * phandles for any nodes, so find_phandle will return NULL.
  231. * Fortunately these machines only have one interrupt controller
  232. * so there isn't in fact any ambiguity. -- paulus
  233. */
  234. if (num_interrupt_controllers == 1)
  235. p = dflt_interrupt_controller;
  236. return p;
  237. }
  238. /*
  239. * Find out the size of each entry of the interrupts property
  240. * for a node.
  241. */
  242. static int __init
  243. prom_n_intr_cells(struct device_node *np)
  244. {
  245. struct device_node *p;
  246. unsigned int *icp;
  247. for (p = np; (p = intr_parent(p)) != NULL; ) {
  248. icp = (unsigned int *)
  249. get_property(p, "#interrupt-cells", NULL);
  250. if (icp != NULL)
  251. return *icp;
  252. if (get_property(p, "interrupt-controller", NULL) != NULL
  253. || get_property(p, "interrupt-map", NULL) != NULL) {
  254. printk("oops, node %s doesn't have #interrupt-cells\n",
  255. p->full_name);
  256. return 1;
  257. }
  258. }
  259. printk("prom_n_intr_cells failed for %s\n", np->full_name);
  260. return 1;
  261. }
  262. /*
  263. * Map an interrupt from a device up to the platform interrupt
  264. * descriptor.
  265. */
  266. static int __init
  267. map_interrupt(unsigned int **irq, struct device_node **ictrler,
  268. struct device_node *np, unsigned int *ints, int nintrc)
  269. {
  270. struct device_node *p, *ipar;
  271. unsigned int *imap, *imask, *ip;
  272. int i, imaplen, match;
  273. int newintrc = 1, newaddrc = 1;
  274. unsigned int *reg;
  275. int naddrc;
  276. reg = (unsigned int *) get_property(np, "reg", NULL);
  277. naddrc = prom_n_addr_cells(np);
  278. p = intr_parent(np);
  279. while (p != NULL) {
  280. if (get_property(p, "interrupt-controller", NULL) != NULL)
  281. /* this node is an interrupt controller, stop here */
  282. break;
  283. imap = (unsigned int *)
  284. get_property(p, "interrupt-map", &imaplen);
  285. if (imap == NULL) {
  286. p = intr_parent(p);
  287. continue;
  288. }
  289. imask = (unsigned int *)
  290. get_property(p, "interrupt-map-mask", NULL);
  291. if (imask == NULL) {
  292. printk("oops, %s has interrupt-map but no mask\n",
  293. p->full_name);
  294. return 0;
  295. }
  296. imaplen /= sizeof(unsigned int);
  297. match = 0;
  298. ipar = NULL;
  299. while (imaplen > 0 && !match) {
  300. /* check the child-interrupt field */
  301. match = 1;
  302. for (i = 0; i < naddrc && match; ++i)
  303. match = ((reg[i] ^ imap[i]) & imask[i]) == 0;
  304. for (; i < naddrc + nintrc && match; ++i)
  305. match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0;
  306. imap += naddrc + nintrc;
  307. imaplen -= naddrc + nintrc;
  308. /* grab the interrupt parent */
  309. ipar = find_phandle((phandle) *imap++);
  310. --imaplen;
  311. if (ipar == NULL && num_interrupt_controllers == 1)
  312. /* cope with BootX not giving us phandles */
  313. ipar = dflt_interrupt_controller;
  314. if (ipar == NULL) {
  315. printk("oops, no int parent %x in map of %s\n",
  316. imap[-1], p->full_name);
  317. return 0;
  318. }
  319. /* find the parent's # addr and intr cells */
  320. ip = (unsigned int *)
  321. get_property(ipar, "#interrupt-cells", NULL);
  322. if (ip == NULL) {
  323. printk("oops, no #interrupt-cells on %s\n",
  324. ipar->full_name);
  325. return 0;
  326. }
  327. newintrc = *ip;
  328. ip = (unsigned int *)
  329. get_property(ipar, "#address-cells", NULL);
  330. newaddrc = (ip == NULL)? 0: *ip;
  331. imap += newaddrc + newintrc;
  332. imaplen -= newaddrc + newintrc;
  333. }
  334. if (imaplen < 0) {
  335. printk("oops, error decoding int-map on %s, len=%d\n",
  336. p->full_name, imaplen);
  337. return 0;
  338. }
  339. if (!match) {
  340. printk("oops, no match in %s int-map for %s\n",
  341. p->full_name, np->full_name);
  342. return 0;
  343. }
  344. p = ipar;
  345. naddrc = newaddrc;
  346. nintrc = newintrc;
  347. ints = imap - nintrc;
  348. reg = ints - naddrc;
  349. }
  350. if (p == NULL)
  351. printk("hmmm, int tree for %s doesn't have ctrler\n",
  352. np->full_name);
  353. *irq = ints;
  354. *ictrler = p;
  355. return nintrc;
  356. }
  357. /*
  358. * New version of finish_node_interrupts.
  359. */
  360. static unsigned long __init
  361. finish_node_interrupts(struct device_node *np, unsigned long mem_start)
  362. {
  363. unsigned int *ints;
  364. int intlen, intrcells;
  365. int i, j, n, offset;
  366. unsigned int *irq;
  367. struct device_node *ic;
  368. ints = (unsigned int *) get_property(np, "interrupts", &intlen);
  369. if (ints == NULL)
  370. return mem_start;
  371. intrcells = prom_n_intr_cells(np);
  372. intlen /= intrcells * sizeof(unsigned int);
  373. np->n_intrs = intlen;
  374. np->intrs = (struct interrupt_info *) mem_start;
  375. mem_start += intlen * sizeof(struct interrupt_info);
  376. for (i = 0; i < intlen; ++i) {
  377. np->intrs[i].line = 0;
  378. np->intrs[i].sense = 1;
  379. n = map_interrupt(&irq, &ic, np, ints, intrcells);
  380. if (n <= 0)
  381. continue;
  382. offset = 0;
  383. /*
  384. * On a CHRP we have an 8259 which is subordinate to
  385. * the openpic in the interrupt tree, but we want the
  386. * openpic's interrupt numbers offsetted, not the 8259's.
  387. * So we apply the offset if the controller is at the
  388. * root of the interrupt tree, i.e. has no interrupt-parent.
  389. * This doesn't cope with the general case of multiple
  390. * cascaded interrupt controllers, but then neither will
  391. * irq.c at the moment either. -- paulus
  392. * The G5 triggers that code, I add a machine test. On
  393. * those machines, we want to offset interrupts from the
  394. * second openpic by 128 -- BenH
  395. */
  396. if (_machine != _MACH_Pmac && num_interrupt_controllers > 1
  397. && ic != NULL
  398. && get_property(ic, "interrupt-parent", NULL) == NULL)
  399. offset = 16;
  400. else if (_machine == _MACH_Pmac && num_interrupt_controllers > 1
  401. && ic != NULL && ic->parent != NULL) {
  402. char *name = get_property(ic->parent, "name", NULL);
  403. if (name && !strcmp(name, "u3"))
  404. offset = 128;
  405. }
  406. np->intrs[i].line = irq[0] + offset;
  407. if (n > 1)
  408. np->intrs[i].sense = irq[1];
  409. if (n > 2) {
  410. printk("hmmm, got %d intr cells for %s:", n,
  411. np->full_name);
  412. for (j = 0; j < n; ++j)
  413. printk(" %d", irq[j]);
  414. printk("\n");
  415. }
  416. ints += intrcells;
  417. }
  418. return mem_start;
  419. }
  420. /*
  421. * When BootX makes a copy of the device tree from the MacOS
  422. * Name Registry, it is in the format we use but all of the pointers
  423. * are offsets from the start of the tree.
  424. * This procedure updates the pointers.
  425. */
  426. void __init
  427. relocate_nodes(void)
  428. {
  429. unsigned long base;
  430. struct device_node *np;
  431. struct property *pp;
  432. #define ADDBASE(x) (x = (typeof (x))((x)? ((unsigned long)(x) + base): 0))
  433. base = (unsigned long) boot_infos + boot_infos->deviceTreeOffset;
  434. allnodes = (struct device_node *)(base + 4);
  435. for (np = allnodes; np != 0; np = np->allnext) {
  436. ADDBASE(np->full_name);
  437. ADDBASE(np->properties);
  438. ADDBASE(np->parent);
  439. ADDBASE(np->child);
  440. ADDBASE(np->sibling);
  441. ADDBASE(np->allnext);
  442. for (pp = np->properties; pp != 0; pp = pp->next) {
  443. ADDBASE(pp->name);
  444. ADDBASE(pp->value);
  445. ADDBASE(pp->next);
  446. }
  447. }
  448. }
  449. int
  450. prom_n_addr_cells(struct device_node* np)
  451. {
  452. int* ip;
  453. do {
  454. if (np->parent)
  455. np = np->parent;
  456. ip = (int *) get_property(np, "#address-cells", NULL);
  457. if (ip != NULL)
  458. return *ip;
  459. } while (np->parent);
  460. /* No #address-cells property for the root node, default to 1 */
  461. return 1;
  462. }
  463. int
  464. prom_n_size_cells(struct device_node* np)
  465. {
  466. int* ip;
  467. do {
  468. if (np->parent)
  469. np = np->parent;
  470. ip = (int *) get_property(np, "#size-cells", NULL);
  471. if (ip != NULL)
  472. return *ip;
  473. } while (np->parent);
  474. /* No #size-cells property for the root node, default to 1 */
  475. return 1;
  476. }
  477. static unsigned long __init
  478. map_addr(struct device_node *np, unsigned long space, unsigned long addr)
  479. {
  480. int na;
  481. unsigned int *ranges;
  482. int rlen = 0;
  483. unsigned int type;
  484. type = (space >> 24) & 3;
  485. if (type == 0)
  486. return addr;
  487. while ((np = np->parent) != NULL) {
  488. if (strcmp(np->type, "pci") != 0)
  489. continue;
  490. /* PCI bridge: map the address through the ranges property */
  491. na = prom_n_addr_cells(np);
  492. ranges = (unsigned int *) get_property(np, "ranges", &rlen);
  493. while ((rlen -= (na + 5) * sizeof(unsigned int)) >= 0) {
  494. if (((ranges[0] >> 24) & 3) == type
  495. && ranges[2] <= addr
  496. && addr - ranges[2] < ranges[na+4]) {
  497. /* ok, this matches, translate it */
  498. addr += ranges[na+2] - ranges[2];
  499. break;
  500. }
  501. ranges += na + 5;
  502. }
  503. }
  504. return addr;
  505. }
  506. static unsigned long __init
  507. interpret_pci_props(struct device_node *np, unsigned long mem_start,
  508. int naddrc, int nsizec)
  509. {
  510. struct address_range *adr;
  511. struct pci_reg_property *pci_addrs;
  512. int i, l, *ip;
  513. pci_addrs = (struct pci_reg_property *)
  514. get_property(np, "assigned-addresses", &l);
  515. if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {
  516. i = 0;
  517. adr = (struct address_range *) mem_start;
  518. while ((l -= sizeof(struct pci_reg_property)) >= 0) {
  519. adr[i].space = pci_addrs[i].addr.a_hi;
  520. adr[i].address = map_addr(np, pci_addrs[i].addr.a_hi,
  521. pci_addrs[i].addr.a_lo);
  522. adr[i].size = pci_addrs[i].size_lo;
  523. ++i;
  524. }
  525. np->addrs = adr;
  526. np->n_addrs = i;
  527. mem_start += i * sizeof(struct address_range);
  528. }
  529. if (use_of_interrupt_tree)
  530. return mem_start;
  531. ip = (int *) get_property(np, "AAPL,interrupts", &l);
  532. if (ip == 0 && np->parent)
  533. ip = (int *) get_property(np->parent, "AAPL,interrupts", &l);
  534. if (ip == 0)
  535. ip = (int *) get_property(np, "interrupts", &l);
  536. if (ip != 0) {
  537. np->intrs = (struct interrupt_info *) mem_start;
  538. np->n_intrs = l / sizeof(int);
  539. mem_start += np->n_intrs * sizeof(struct interrupt_info);
  540. for (i = 0; i < np->n_intrs; ++i) {
  541. np->intrs[i].line = *ip++;
  542. np->intrs[i].sense = 1;
  543. }
  544. }
  545. return mem_start;
  546. }
  547. static unsigned long __init
  548. interpret_dbdma_props(struct device_node *np, unsigned long mem_start,
  549. int naddrc, int nsizec)
  550. {
  551. struct reg_property *rp;
  552. struct address_range *adr;
  553. unsigned long base_address;
  554. int i, l, *ip;
  555. struct device_node *db;
  556. base_address = 0;
  557. for (db = np->parent; db != NULL; db = db->parent) {
  558. if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
  559. base_address = db->addrs[0].address;
  560. break;
  561. }
  562. }
  563. rp = (struct reg_property *) get_property(np, "reg", &l);
  564. if (rp != 0 && l >= sizeof(struct reg_property)) {
  565. i = 0;
  566. adr = (struct address_range *) mem_start;
  567. while ((l -= sizeof(struct reg_property)) >= 0) {
  568. adr[i].space = 2;
  569. adr[i].address = rp[i].address + base_address;
  570. adr[i].size = rp[i].size;
  571. ++i;
  572. }
  573. np->addrs = adr;
  574. np->n_addrs = i;
  575. mem_start += i * sizeof(struct address_range);
  576. }
  577. if (use_of_interrupt_tree)
  578. return mem_start;
  579. ip = (int *) get_property(np, "AAPL,interrupts", &l);
  580. if (ip == 0)
  581. ip = (int *) get_property(np, "interrupts", &l);
  582. if (ip != 0) {
  583. np->intrs = (struct interrupt_info *) mem_start;
  584. np->n_intrs = l / sizeof(int);
  585. mem_start += np->n_intrs * sizeof(struct interrupt_info);
  586. for (i = 0; i < np->n_intrs; ++i) {
  587. np->intrs[i].line = *ip++;
  588. np->intrs[i].sense = 1;
  589. }
  590. }
  591. return mem_start;
  592. }
  593. static unsigned long __init
  594. interpret_macio_props(struct device_node *np, unsigned long mem_start,
  595. int naddrc, int nsizec)
  596. {
  597. struct reg_property *rp;
  598. struct address_range *adr;
  599. unsigned long base_address;
  600. int i, l, *ip;
  601. struct device_node *db;
  602. base_address = 0;
  603. for (db = np->parent; db != NULL; db = db->parent) {
  604. if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
  605. base_address = db->addrs[0].address;
  606. break;
  607. }
  608. }
  609. rp = (struct reg_property *) get_property(np, "reg", &l);
  610. if (rp != 0 && l >= sizeof(struct reg_property)) {
  611. i = 0;
  612. adr = (struct address_range *) mem_start;
  613. while ((l -= sizeof(struct reg_property)) >= 0) {
  614. adr[i].space = 2;
  615. adr[i].address = rp[i].address + base_address;
  616. adr[i].size = rp[i].size;
  617. ++i;
  618. }
  619. np->addrs = adr;
  620. np->n_addrs = i;
  621. mem_start += i * sizeof(struct address_range);
  622. }
  623. if (use_of_interrupt_tree)
  624. return mem_start;
  625. ip = (int *) get_property(np, "interrupts", &l);
  626. if (ip == 0)
  627. ip = (int *) get_property(np, "AAPL,interrupts", &l);
  628. if (ip != 0) {
  629. np->intrs = (struct interrupt_info *) mem_start;
  630. np->n_intrs = l / sizeof(int);
  631. for (i = 0; i < np->n_intrs; ++i) {
  632. np->intrs[i].line = *ip++;
  633. np->intrs[i].sense = 1;
  634. }
  635. mem_start += np->n_intrs * sizeof(struct interrupt_info);
  636. }
  637. return mem_start;
  638. }
  639. static unsigned long __init
  640. interpret_isa_props(struct device_node *np, unsigned long mem_start,
  641. int naddrc, int nsizec)
  642. {
  643. struct isa_reg_property *rp;
  644. struct address_range *adr;
  645. int i, l, *ip;
  646. rp = (struct isa_reg_property *) get_property(np, "reg", &l);
  647. if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
  648. i = 0;
  649. adr = (struct address_range *) mem_start;
  650. while ((l -= sizeof(struct reg_property)) >= 0) {
  651. adr[i].space = rp[i].space;
  652. adr[i].address = rp[i].address
  653. + (adr[i].space? 0: _ISA_MEM_BASE);
  654. adr[i].size = rp[i].size;
  655. ++i;
  656. }
  657. np->addrs = adr;
  658. np->n_addrs = i;
  659. mem_start += i * sizeof(struct address_range);
  660. }
  661. if (use_of_interrupt_tree)
  662. return mem_start;
  663. ip = (int *) get_property(np, "interrupts", &l);
  664. if (ip != 0) {
  665. np->intrs = (struct interrupt_info *) mem_start;
  666. np->n_intrs = l / (2 * sizeof(int));
  667. mem_start += np->n_intrs * sizeof(struct interrupt_info);
  668. for (i = 0; i < np->n_intrs; ++i) {
  669. np->intrs[i].line = *ip++;
  670. np->intrs[i].sense = *ip++;
  671. }
  672. }
  673. return mem_start;
  674. }
  675. static unsigned long __init
  676. interpret_root_props(struct device_node *np, unsigned long mem_start,
  677. int naddrc, int nsizec)
  678. {
  679. struct address_range *adr;
  680. int i, l, *ip;
  681. unsigned int *rp;
  682. int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
  683. rp = (unsigned int *) get_property(np, "reg", &l);
  684. if (rp != 0 && l >= rpsize) {
  685. i = 0;
  686. adr = (struct address_range *) mem_start;
  687. while ((l -= rpsize) >= 0) {
  688. adr[i].space = (naddrc >= 2? rp[naddrc-2]: 2);
  689. adr[i].address = rp[naddrc - 1];
  690. adr[i].size = rp[naddrc + nsizec - 1];
  691. ++i;
  692. rp += naddrc + nsizec;
  693. }
  694. np->addrs = adr;
  695. np->n_addrs = i;
  696. mem_start += i * sizeof(struct address_range);
  697. }
  698. if (use_of_interrupt_tree)
  699. return mem_start;
  700. ip = (int *) get_property(np, "AAPL,interrupts", &l);
  701. if (ip == 0)
  702. ip = (int *) get_property(np, "interrupts", &l);
  703. if (ip != 0) {
  704. np->intrs = (struct interrupt_info *) mem_start;
  705. np->n_intrs = l / sizeof(int);
  706. mem_start += np->n_intrs * sizeof(struct interrupt_info);
  707. for (i = 0; i < np->n_intrs; ++i) {
  708. np->intrs[i].line = *ip++;
  709. np->intrs[i].sense = 1;
  710. }
  711. }
  712. return mem_start;
  713. }
  714. /*
  715. * Work out the sense (active-low level / active-high edge)
  716. * of each interrupt from the device tree.
  717. */
  718. void __init
  719. prom_get_irq_senses(unsigned char *senses, int off, int max)
  720. {
  721. struct device_node *np;
  722. int i, j;
  723. /* default to level-triggered */
  724. memset(senses, 1, max - off);
  725. if (!use_of_interrupt_tree)
  726. return;
  727. for (np = allnodes; np != 0; np = np->allnext) {
  728. for (j = 0; j < np->n_intrs; j++) {
  729. i = np->intrs[j].line;
  730. if (i >= off && i < max) {
  731. if (np->intrs[j].sense == 1)
  732. senses[i-off] = (IRQ_SENSE_LEVEL
  733. | IRQ_POLARITY_NEGATIVE);
  734. else
  735. senses[i-off] = (IRQ_SENSE_EDGE
  736. | IRQ_POLARITY_POSITIVE);
  737. }
  738. }
  739. }
  740. }
  741. /*
  742. * Construct and return a list of the device_nodes with a given name.
  743. */
  744. struct device_node *
  745. find_devices(const char *name)
  746. {
  747. struct device_node *head, **prevp, *np;
  748. prevp = &head;
  749. for (np = allnodes; np != 0; np = np->allnext) {
  750. if (np->name != 0 && strcasecmp(np->name, name) == 0) {
  751. *prevp = np;
  752. prevp = &np->next;
  753. }
  754. }
  755. *prevp = NULL;
  756. return head;
  757. }
  758. /*
  759. * Construct and return a list of the device_nodes with a given type.
  760. */
  761. struct device_node *
  762. find_type_devices(const char *type)
  763. {
  764. struct device_node *head, **prevp, *np;
  765. prevp = &head;
  766. for (np = allnodes; np != 0; np = np->allnext) {
  767. if (np->type != 0 && strcasecmp(np->type, type) == 0) {
  768. *prevp = np;
  769. prevp = &np->next;
  770. }
  771. }
  772. *prevp = NULL;
  773. return head;
  774. }
  775. /*
  776. * Returns all nodes linked together
  777. */
  778. struct device_node * __openfirmware
  779. find_all_nodes(void)
  780. {
  781. struct device_node *head, **prevp, *np;
  782. prevp = &head;
  783. for (np = allnodes; np != 0; np = np->allnext) {
  784. *prevp = np;
  785. prevp = &np->next;
  786. }
  787. *prevp = NULL;
  788. return head;
  789. }
  790. /* Checks if the given "compat" string matches one of the strings in
  791. * the device's "compatible" property
  792. */
  793. int
  794. device_is_compatible(struct device_node *device, const char *compat)
  795. {
  796. const char* cp;
  797. int cplen, l;
  798. cp = (char *) get_property(device, "compatible", &cplen);
  799. if (cp == NULL)
  800. return 0;
  801. while (cplen > 0) {
  802. if (strncasecmp(cp, compat, strlen(compat)) == 0)
  803. return 1;
  804. l = strlen(cp) + 1;
  805. cp += l;
  806. cplen -= l;
  807. }
  808. return 0;
  809. }
  810. /*
  811. * Indicates whether the root node has a given value in its
  812. * compatible property.
  813. */
  814. int
  815. machine_is_compatible(const char *compat)
  816. {
  817. struct device_node *root;
  818. root = find_path_device("/");
  819. if (root == 0)
  820. return 0;
  821. return device_is_compatible(root, compat);
  822. }
  823. /*
  824. * Construct and return a list of the device_nodes with a given type
  825. * and compatible property.
  826. */
  827. struct device_node *
  828. find_compatible_devices(const char *type, const char *compat)
  829. {
  830. struct device_node *head, **prevp, *np;
  831. prevp = &head;
  832. for (np = allnodes; np != 0; np = np->allnext) {
  833. if (type != NULL
  834. && !(np->type != 0 && strcasecmp(np->type, type) == 0))
  835. continue;
  836. if (device_is_compatible(np, compat)) {
  837. *prevp = np;
  838. prevp = &np->next;
  839. }
  840. }
  841. *prevp = NULL;
  842. return head;
  843. }
  844. /*
  845. * Find the device_node with a given full_name.
  846. */
  847. struct device_node *
  848. find_path_device(const char *path)
  849. {
  850. struct device_node *np;
  851. for (np = allnodes; np != 0; np = np->allnext)
  852. if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
  853. return np;
  854. return NULL;
  855. }
  856. /*******
  857. *
  858. * New implementation of the OF "find" APIs, return a refcounted
  859. * object, call of_node_put() when done. Currently, still lacks
  860. * locking as old implementation, this is beeing done for ppc64.
  861. *
  862. * Note that property management will need some locking as well,
  863. * this isn't dealt with yet
  864. *
  865. *******/
  866. /**
  867. * of_find_node_by_name - Find a node by it's "name" property
  868. * @from: The node to start searching from or NULL, the node
  869. * you pass will not be searched, only the next one
  870. * will; typically, you pass what the previous call
  871. * returned. of_node_put() will be called on it
  872. * @name: The name string to match against
  873. *
  874. * Returns a node pointer with refcount incremented, use
  875. * of_node_put() on it when done.
  876. */
  877. struct device_node *of_find_node_by_name(struct device_node *from,
  878. const char *name)
  879. {
  880. struct device_node *np = from ? from->allnext : allnodes;
  881. for (; np != 0; np = np->allnext)
  882. if (np->name != 0 && strcasecmp(np->name, name) == 0)
  883. break;
  884. if (from)
  885. of_node_put(from);
  886. return of_node_get(np);
  887. }
  888. /**
  889. * of_find_node_by_type - Find a node by it's "device_type" property
  890. * @from: The node to start searching from or NULL, the node
  891. * you pass will not be searched, only the next one
  892. * will; typically, you pass what the previous call
  893. * returned. of_node_put() will be called on it
  894. * @name: The type string to match against
  895. *
  896. * Returns a node pointer with refcount incremented, use
  897. * of_node_put() on it when done.
  898. */
  899. struct device_node *of_find_node_by_type(struct device_node *from,
  900. const char *type)
  901. {
  902. struct device_node *np = from ? from->allnext : allnodes;
  903. for (; np != 0; np = np->allnext)
  904. if (np->type != 0 && strcasecmp(np->type, type) == 0)
  905. break;
  906. if (from)
  907. of_node_put(from);
  908. return of_node_get(np);
  909. }
  910. /**
  911. * of_find_compatible_node - Find a node based on type and one of the
  912. * tokens in it's "compatible" property
  913. * @from: The node to start searching from or NULL, the node
  914. * you pass will not be searched, only the next one
  915. * will; typically, you pass what the previous call
  916. * returned. of_node_put() will be called on it
  917. * @type: The type string to match "device_type" or NULL to ignore
  918. * @compatible: The string to match to one of the tokens in the device
  919. * "compatible" list.
  920. *
  921. * Returns a node pointer with refcount incremented, use
  922. * of_node_put() on it when done.
  923. */
  924. struct device_node *of_find_compatible_node(struct device_node *from,
  925. const char *type, const char *compatible)
  926. {
  927. struct device_node *np = from ? from->allnext : allnodes;
  928. for (; np != 0; np = np->allnext) {
  929. if (type != NULL
  930. && !(np->type != 0 && strcasecmp(np->type, type) == 0))
  931. continue;
  932. if (device_is_compatible(np, compatible))
  933. break;
  934. }
  935. if (from)
  936. of_node_put(from);
  937. return of_node_get(np);
  938. }
  939. /**
  940. * of_find_node_by_path - Find a node matching a full OF path
  941. * @path: The full path to match
  942. *
  943. * Returns a node pointer with refcount incremented, use
  944. * of_node_put() on it when done.
  945. */
  946. struct device_node *of_find_node_by_path(const char *path)
  947. {
  948. struct device_node *np = allnodes;
  949. for (; np != 0; np = np->allnext)
  950. if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
  951. break;
  952. return of_node_get(np);
  953. }
  954. /**
  955. * of_find_all_nodes - Get next node in global list
  956. * @prev: Previous node or NULL to start iteration
  957. * of_node_put() will be called on it
  958. *
  959. * Returns a node pointer with refcount incremented, use
  960. * of_node_put() on it when done.
  961. */
  962. struct device_node *of_find_all_nodes(struct device_node *prev)
  963. {
  964. return of_node_get(prev ? prev->allnext : allnodes);
  965. }
  966. /**
  967. * of_get_parent - Get a node's parent if any
  968. * @node: Node to get parent
  969. *
  970. * Returns a node pointer with refcount incremented, use
  971. * of_node_put() on it when done.
  972. */
  973. struct device_node *of_get_parent(const struct device_node *node)
  974. {
  975. return node ? of_node_get(node->parent) : NULL;
  976. }
  977. /**
  978. * of_get_next_child - Iterate a node childs
  979. * @node: parent node
  980. * @prev: previous child of the parent node, or NULL to get first
  981. *
  982. * Returns a node pointer with refcount incremented, use
  983. * of_node_put() on it when done.
  984. */
  985. struct device_node *of_get_next_child(const struct device_node *node,
  986. struct device_node *prev)
  987. {
  988. struct device_node *next = prev ? prev->sibling : node->child;
  989. for (; next != 0; next = next->sibling)
  990. if (of_node_get(next))
  991. break;
  992. if (prev)
  993. of_node_put(prev);
  994. return next;
  995. }
  996. /**
  997. * of_node_get - Increment refcount of a node
  998. * @node: Node to inc refcount, NULL is supported to
  999. * simplify writing of callers
  1000. *
  1001. * Returns the node itself or NULL if gone. Current implementation
  1002. * does nothing as we don't yet do dynamic node allocation on ppc32
  1003. */
  1004. struct device_node *of_node_get(struct device_node *node)
  1005. {
  1006. return node;
  1007. }
  1008. /**
  1009. * of_node_put - Decrement refcount of a node
  1010. * @node: Node to dec refcount, NULL is supported to
  1011. * simplify writing of callers
  1012. *
  1013. * Current implementation does nothing as we don't yet do dynamic node
  1014. * allocation on ppc32
  1015. */
  1016. void of_node_put(struct device_node *node)
  1017. {
  1018. }
  1019. /*
  1020. * Find the device_node with a given phandle.
  1021. */
  1022. static struct device_node * __init
  1023. find_phandle(phandle ph)
  1024. {
  1025. struct device_node *np;
  1026. for (np = allnodes; np != 0; np = np->allnext)
  1027. if (np->node == ph)
  1028. return np;
  1029. return NULL;
  1030. }
  1031. /*
  1032. * Find a property with a given name for a given node
  1033. * and return the value.
  1034. */
  1035. unsigned char *
  1036. get_property(struct device_node *np, const char *name, int *lenp)
  1037. {
  1038. struct property *pp;
  1039. for (pp = np->properties; pp != 0; pp = pp->next)
  1040. if (pp->name != NULL && strcmp(pp->name, name) == 0) {
  1041. if (lenp != 0)
  1042. *lenp = pp->length;
  1043. return pp->value;
  1044. }
  1045. return NULL;
  1046. }
  1047. /*
  1048. * Add a property to a node
  1049. */
  1050. void __openfirmware
  1051. prom_add_property(struct device_node* np, struct property* prop)
  1052. {
  1053. struct property **next = &np->properties;
  1054. prop->next = NULL;
  1055. while (*next)
  1056. next = &(*next)->next;
  1057. *next = prop;
  1058. }
  1059. /* I quickly hacked that one, check against spec ! */
  1060. static inline unsigned long __openfirmware
  1061. bus_space_to_resource_flags(unsigned int bus_space)
  1062. {
  1063. u8 space = (bus_space >> 24) & 0xf;
  1064. if (space == 0)
  1065. space = 0x02;
  1066. if (space == 0x02)
  1067. return IORESOURCE_MEM;
  1068. else if (space == 0x01)
  1069. return IORESOURCE_IO;
  1070. else {
  1071. printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n",
  1072. bus_space);
  1073. return 0;
  1074. }
  1075. }
  1076. static struct resource* __openfirmware
  1077. find_parent_pci_resource(struct pci_dev* pdev, struct address_range *range)
  1078. {
  1079. unsigned long mask;
  1080. int i;
  1081. /* Check this one */
  1082. mask = bus_space_to_resource_flags(range->space);
  1083. for (i=0; i<DEVICE_COUNT_RESOURCE; i++) {
  1084. if ((pdev->resource[i].flags & mask) == mask &&
  1085. pdev->resource[i].start <= range->address &&
  1086. pdev->resource[i].end > range->address) {
  1087. if ((range->address + range->size - 1) > pdev->resource[i].end) {
  1088. /* Add better message */
  1089. printk(KERN_WARNING "PCI/OF resource overlap !\n");
  1090. return NULL;
  1091. }
  1092. break;
  1093. }
  1094. }
  1095. if (i == DEVICE_COUNT_RESOURCE)
  1096. return NULL;
  1097. return &pdev->resource[i];
  1098. }
  1099. /*
  1100. * Request an OF device resource. Currently handles child of PCI devices,
  1101. * or other nodes attached to the root node. Ultimately, put some
  1102. * link to resources in the OF node.
  1103. */
  1104. struct resource* __openfirmware
  1105. request_OF_resource(struct device_node* node, int index, const char* name_postfix)
  1106. {
  1107. struct pci_dev* pcidev;
  1108. u8 pci_bus, pci_devfn;
  1109. unsigned long iomask;
  1110. struct device_node* nd;
  1111. struct resource* parent;
  1112. struct resource *res = NULL;
  1113. int nlen, plen;
  1114. if (index >= node->n_addrs)
  1115. goto fail;
  1116. /* Sanity check on bus space */
  1117. iomask = bus_space_to_resource_flags(node->addrs[index].space);
  1118. if (iomask & IORESOURCE_MEM)
  1119. parent = &iomem_resource;
  1120. else if (iomask & IORESOURCE_IO)
  1121. parent = &ioport_resource;
  1122. else
  1123. goto fail;
  1124. /* Find a PCI parent if any */
  1125. nd = node;
  1126. pcidev = NULL;
  1127. while(nd) {
  1128. if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
  1129. pcidev = pci_find_slot(pci_bus, pci_devfn);
  1130. if (pcidev) break;
  1131. nd = nd->parent;
  1132. }
  1133. if (pcidev)
  1134. parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
  1135. if (!parent) {
  1136. printk(KERN_WARNING "request_OF_resource(%s), parent not found\n",
  1137. node->name);
  1138. goto fail;
  1139. }
  1140. res = __request_region(parent, node->addrs[index].address, node->addrs[index].size, NULL);
  1141. if (!res)
  1142. goto fail;
  1143. nlen = strlen(node->name);
  1144. plen = name_postfix ? strlen(name_postfix) : 0;
  1145. res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL);
  1146. if (res->name) {
  1147. strcpy((char *)res->name, node->name);
  1148. if (plen)
  1149. strcpy((char *)res->name+nlen, name_postfix);
  1150. }
  1151. return res;
  1152. fail:
  1153. return NULL;
  1154. }
  1155. int __openfirmware
  1156. release_OF_resource(struct device_node* node, int index)
  1157. {
  1158. struct pci_dev* pcidev;
  1159. u8 pci_bus, pci_devfn;
  1160. unsigned long iomask, start, end;
  1161. struct device_node* nd;
  1162. struct resource* parent;
  1163. struct resource *res = NULL;
  1164. if (index >= node->n_addrs)
  1165. return -EINVAL;
  1166. /* Sanity check on bus space */
  1167. iomask = bus_space_to_resource_flags(node->addrs[index].space);
  1168. if (iomask & IORESOURCE_MEM)
  1169. parent = &iomem_resource;
  1170. else if (iomask & IORESOURCE_IO)
  1171. parent = &ioport_resource;
  1172. else
  1173. return -EINVAL;
  1174. /* Find a PCI parent if any */
  1175. nd = node;
  1176. pcidev = NULL;
  1177. while(nd) {
  1178. if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
  1179. pcidev = pci_find_slot(pci_bus, pci_devfn);
  1180. if (pcidev) break;
  1181. nd = nd->parent;
  1182. }
  1183. if (pcidev)
  1184. parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
  1185. if (!parent) {
  1186. printk(KERN_WARNING "release_OF_resource(%s), parent not found\n",
  1187. node->name);
  1188. return -ENODEV;
  1189. }
  1190. /* Find us in the parent and its childs */
  1191. res = parent->child;
  1192. start = node->addrs[index].address;
  1193. end = start + node->addrs[index].size - 1;
  1194. while (res) {
  1195. if (res->start == start && res->end == end &&
  1196. (res->flags & IORESOURCE_BUSY))
  1197. break;
  1198. if (res->start <= start && res->end >= end)
  1199. res = res->child;
  1200. else
  1201. res = res->sibling;
  1202. }
  1203. if (!res)
  1204. return -ENODEV;
  1205. if (res->name) {
  1206. kfree(res->name);
  1207. res->name = NULL;
  1208. }
  1209. release_resource(res);
  1210. kfree(res);
  1211. return 0;
  1212. }
  1213. #if 0
  1214. void __openfirmware
  1215. print_properties(struct device_node *np)
  1216. {
  1217. struct property *pp;
  1218. char *cp;
  1219. int i, n;
  1220. for (pp = np->properties; pp != 0; pp = pp->next) {
  1221. printk(KERN_INFO "%s", pp->name);
  1222. for (i = strlen(pp->name); i < 16; ++i)
  1223. printk(" ");
  1224. cp = (char *) pp->value;
  1225. for (i = pp->length; i > 0; --i, ++cp)
  1226. if ((i > 1 && (*cp < 0x20 || *cp > 0x7e))
  1227. || (i == 1 && *cp != 0))
  1228. break;
  1229. if (i == 0 && pp->length > 1) {
  1230. /* looks like a string */
  1231. printk(" %s\n", (char *) pp->value);
  1232. } else {
  1233. /* dump it in hex */
  1234. n = pp->length;
  1235. if (n > 64)
  1236. n = 64;
  1237. if (pp->length % 4 == 0) {
  1238. unsigned int *p = (unsigned int *) pp->value;
  1239. n /= 4;
  1240. for (i = 0; i < n; ++i) {
  1241. if (i != 0 && (i % 4) == 0)
  1242. printk("\n ");
  1243. printk(" %08x", *p++);
  1244. }
  1245. } else {
  1246. unsigned char *bp = pp->value;
  1247. for (i = 0; i < n; ++i) {
  1248. if (i != 0 && (i % 16) == 0)
  1249. printk("\n ");
  1250. printk(" %02x", *bp++);
  1251. }
  1252. }
  1253. printk("\n");
  1254. if (pp->length > 64)
  1255. printk(" ... (length = %d)\n",
  1256. pp->length);
  1257. }
  1258. }
  1259. }
  1260. #endif
  1261. static DEFINE_SPINLOCK(rtas_lock);
  1262. /* this can be called after setup -- Cort */
  1263. int __openfirmware
  1264. call_rtas(const char *service, int nargs, int nret,
  1265. unsigned long *outputs, ...)
  1266. {
  1267. va_list list;
  1268. int i;
  1269. unsigned long s;
  1270. struct device_node *rtas;
  1271. int *tokp;
  1272. union {
  1273. unsigned long words[16];
  1274. double align;
  1275. } u;
  1276. rtas = find_devices("rtas");
  1277. if (rtas == NULL)
  1278. return -1;
  1279. tokp = (int *) get_property(rtas, service, NULL);
  1280. if (tokp == NULL) {
  1281. printk(KERN_ERR "No RTAS service called %s\n", service);
  1282. return -1;
  1283. }
  1284. u.words[0] = *tokp;
  1285. u.words[1] = nargs;
  1286. u.words[2] = nret;
  1287. va_start(list, outputs);
  1288. for (i = 0; i < nargs; ++i)
  1289. u.words[i+3] = va_arg(list, unsigned long);
  1290. va_end(list);
  1291. /*
  1292. * RTAS doesn't use floating point.
  1293. * Or at least, according to the CHRP spec we enter RTAS
  1294. * with FP disabled, and it doesn't change the FP registers.
  1295. * -- paulus.
  1296. */
  1297. spin_lock_irqsave(&rtas_lock, s);
  1298. enter_rtas((void *)__pa(&u));
  1299. spin_unlock_irqrestore(&rtas_lock, s);
  1300. if (nret > 1 && outputs != NULL)
  1301. for (i = 0; i < nret-1; ++i)
  1302. outputs[i] = u.words[i+nargs+4];
  1303. return u.words[nargs+3];
  1304. }