prom.c 36 KB

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