prom.c 35 KB

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