embed_config.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:15k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: %F% %I% %G% %U% %#%
  3.  */
  4. /* Board specific functions for those embedded 8xx boards that do
  5.  * not have boot monitor support for board information.
  6.  *
  7.  * This program is free software; you can redistribute  it and/or modify it
  8.  * under  the terms of  the GNU General  Public License as published by the
  9.  * Free Software Foundation;  either version 2 of the  License, or (at your
  10.  * option) any later version.
  11.  */
  12. #include <linux/types.h>
  13. #include <linux/config.h>
  14. #ifdef CONFIG_8xx
  15. #include <asm/mpc8xx.h>
  16. #endif
  17. #ifdef CONFIG_8260
  18. #include <asm/mpc8260.h>
  19. #include <asm/immap_8260.h>
  20. #endif
  21. #ifdef CONFIG_4xx
  22. #include <asm/io.h>
  23. #endif
  24. #if defined(CONFIG_405GP) || defined(CONFIG_NP405H) || defined(CONFIG_NP405L)
  25. #include <linux/netdevice.h>
  26. #endif
  27. /* For those boards that don't provide one.
  28. */
  29. #if !defined(CONFIG_MBX)
  30. static bd_t bdinfo;
  31. #endif
  32. /* IIC functions.
  33.  * These are just the basic master read/write operations so we can
  34.  * examine serial EEPROM.
  35.  */
  36. extern void iic_read(uint devaddr, u_char *buf, uint offset, uint count);
  37. /* Supply a default Ethernet address for those eval boards that don't
  38.  * ship with one.  This is an address from the MBX board I have, so
  39.  * it is unlikely you will find it on your network.
  40.  */
  41. static ushort def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };
  42. #if defined(CONFIG_MBX)
  43. /* The MBX hands us a pretty much ready to go board descriptor.  This
  44.  * is where the idea started in the first place.
  45.  */
  46. void
  47. embed_config(bd_t **bdp)
  48. {
  49. u_char *mp;
  50. u_char eebuf[128];
  51. int i;
  52. bd_t    *bd;
  53. bd = *bdp;
  54. /* Read the first 128 bytes of the EEPROM.  There is more,
  55.  * but this is all we need.
  56.  */
  57. iic_read(0xa4, eebuf, 0, 128);
  58. /* All we are looking for is the Ethernet MAC address.  The
  59.  * first 8 bytes are 'MOTOROLA', so check for part of that.
  60.  * If it's there, assume we have a valid MAC address.  If not,
  61.  * grab our default one.
  62.  */
  63. if ((*(uint *)eebuf) == 0x4d4f544f)
  64. mp = &eebuf[0x4c];
  65. else
  66. mp = (u_char *)def_enet_addr;
  67. for (i=0; i<6; i++)
  68. bd->bi_enetaddr[i] = *mp++;
  69. /* The boot rom passes these to us in MHz.  Linux now expects
  70.  * them to be in Hz.
  71.  */
  72. bd->bi_intfreq *= 1000000;
  73. bd->bi_busfreq *= 1000000;
  74. /* Stuff a baud rate here as well.
  75. */
  76. bd->bi_baudrate = 9600;
  77. }
  78. #endif /* CONFIG_MBX */
  79. #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || 
  80. defined(CONFIG_RPX6) || defined(CONFIG_EP405)
  81. /* Helper functions for Embedded Planet boards.
  82. */
  83. /* Because I didn't find anything that would do this.......
  84. */
  85. u_char
  86. aschex_to_byte(u_char *cp)
  87. {
  88. u_char byte, c;
  89. c = *cp++;
  90. if ((c >= 'A') && (c <= 'F')) {
  91. c -= 'A';
  92. c += 10;
  93. } else if ((c >= 'a') && (c <= 'f')) {
  94. c -= 'a';
  95. c += 10;
  96. } else
  97. c -= '0';
  98. byte = c * 16;
  99. c = *cp;
  100. if ((c >= 'A') && (c <= 'F')) {
  101. c -= 'A';
  102. c += 10;
  103. } else if ((c >= 'a') && (c <= 'f')) {
  104. c -= 'a';
  105. c += 10;
  106. } else
  107. c -= '0';
  108. byte += c;
  109. return(byte);
  110. }
  111. static void
  112. rpx_eth(bd_t *bd, u_char *cp)
  113. {
  114. int i;
  115. for (i=0; i<6; i++) {
  116. bd->bi_enetaddr[i] = aschex_to_byte(cp);
  117. cp += 2;
  118. }
  119. }
  120. #ifdef CONFIG_RPX6
  121. static uint
  122. rpx_baseten(u_char *cp)
  123. {
  124. uint retval;
  125. retval = 0;
  126. while (*cp != 'n') {
  127. retval *= 10;
  128. retval += (*cp) - '0';
  129. cp++;
  130. }
  131. return(retval);
  132. }
  133. #endif
  134. #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
  135. static void
  136. rpx_brate(bd_t *bd, u_char *cp)
  137. {
  138. uint rate;
  139. rate = 0;
  140. while (*cp != 'n') {
  141. rate *= 10;
  142. rate += (*cp) - '0';
  143. cp++;
  144. }
  145. bd->bi_baudrate = rate * 100;
  146. }
  147. static void
  148. rpx_cpuspeed(bd_t *bd, u_char *cp)
  149. {
  150. uint num, den;
  151. num = den = 0;
  152. while (*cp != 'n') {
  153. num *= 10;
  154. num += (*cp) - '0';
  155. cp++;
  156. if (*cp == '/') {
  157. cp++;
  158. den = (*cp) - '0';
  159. break;
  160. }
  161. }
  162. /* I don't know why the RPX just can't state the actual
  163.  * CPU speed.....
  164.  */
  165. if (den) {
  166. num /= den;
  167. num *= den;
  168. }
  169. bd->bi_intfreq = bd->bi_busfreq = num * 1000000;
  170. /* The 8xx can only run a maximum 50 MHz bus speed (until
  171.  * Motorola changes this :-).  Greater than 50 MHz parts
  172.  * run internal/2 for bus speed.
  173.  */
  174. if (num > 50)
  175. bd->bi_busfreq /= 2;
  176. }
  177. #endif
  178. #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_EP405)
  179. static void
  180. rpx_memsize(bd_t *bd, u_char *cp)
  181. {
  182. uint size;
  183. size = 0;
  184. while (*cp != 'n') {
  185. size *= 10;
  186. size += (*cp) - '0';
  187. cp++;
  188. }
  189. bd->bi_memsize = size * 1024 * 1024;
  190. }
  191. #endif /* LITE || CLASSIC || EP405 */
  192. #endif /* Embedded Planet boards */
  193. #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
  194. /* Read the EEPROM on the RPX-Lite board.
  195. */
  196. void
  197. embed_config(bd_t **bdp)
  198. {
  199. u_char eebuf[256], *cp;
  200. bd_t *bd;
  201. /* Read the first 256 bytes of the EEPROM.  I think this
  202.  * is really all there is, and I hope if it gets bigger the
  203.  * info we want is still up front.
  204.  */
  205. bd = &bdinfo;
  206. *bdp = bd;
  207. #if 1
  208. iic_read(0xa8, eebuf, 0, 128);
  209. iic_read(0xa8, &eebuf[128], 128, 128);
  210. /* We look for two things, the Ethernet address and the
  211.  * serial baud rate.  The records are separated by
  212.  * newlines.
  213.  */
  214. cp = eebuf;
  215. for (;;) {
  216. if (*cp == 'E') {
  217. cp++;
  218. if (*cp == 'A') {
  219. cp += 2;
  220. rpx_eth(bd, cp);
  221. }
  222. }
  223. if (*cp == 'S') {
  224. cp++;
  225. if (*cp == 'B') {
  226. cp += 2;
  227. rpx_brate(bd, cp);
  228. }
  229. }
  230. if (*cp == 'D') {
  231. cp++;
  232. if (*cp == '1') {
  233. cp += 2;
  234. rpx_memsize(bd, cp);
  235. }
  236. }
  237. if (*cp == 'H') {
  238. cp++;
  239. if (*cp == 'Z') {
  240. cp += 2;
  241. rpx_cpuspeed(bd, cp);
  242. }
  243. }
  244. /* Scan to the end of the record.
  245. */
  246. while ((*cp != 'n') && (*cp != 0xff))
  247. cp++;
  248. /* If the next character is a 0 or ff, we are done.
  249. */
  250. cp++;
  251. if ((*cp == 0) || (*cp == 0xff))
  252. break;
  253. }
  254. bd->bi_memstart = 0;
  255. #else
  256. /* For boards without initialized EEPROM.
  257. */
  258. bd->bi_memstart = 0;
  259. bd->bi_memsize = (8 * 1024 * 1024);
  260. bd->bi_intfreq = 48000000;
  261. bd->bi_busfreq = 48000000;
  262. bd->bi_baudrate = 9600;
  263. #endif
  264. }
  265. #endif /* RPXLITE || RPXCLASSIC */
  266. #ifdef CONFIG_BSEIP
  267. /* Build a board information structure for the BSE ip-Engine.
  268.  * There is more to come since we will add some environment
  269.  * variables and a function to read them.
  270.  */
  271. void
  272. embed_config(bd_t **bdp)
  273. {
  274. u_char *cp;
  275. int i;
  276. bd_t *bd;
  277. bd = &bdinfo;
  278. *bdp = bd;
  279. /* Baud rate and processor speed will eventually come
  280.  * from the environment variables.
  281.  */
  282. bd->bi_baudrate = 9600;
  283. /* Get the Ethernet station address from the Flash ROM.
  284. */
  285. cp = (u_char *)0xfe003ffa;
  286. for (i=0; i<6; i++) {
  287. bd->bi_enetaddr[i] = *cp++;
  288. }
  289. /* The rest of this should come from the environment as well.
  290. */
  291. bd->bi_memstart = 0;
  292. bd->bi_memsize = (16 * 1024 * 1024);
  293. bd->bi_intfreq = 48000000;
  294. bd->bi_busfreq = 48000000;
  295. }
  296. #endif /* BSEIP */
  297. #ifdef CONFIG_FADS
  298. /* Build a board information structure for the FADS.
  299.  */
  300. void
  301. embed_config(bd_t **bdp)
  302. {
  303. u_char *cp;
  304. int i;
  305. bd_t *bd;
  306. bd = &bdinfo;
  307. *bdp = bd;
  308. /* Just fill in some known values.
  309.  */
  310. bd->bi_baudrate = 9600;
  311. /* Use default enet.
  312. */
  313. cp = (u_char *)def_enet_addr;
  314. for (i=0; i<6; i++) {
  315. bd->bi_enetaddr[i] = *cp++;
  316. }
  317. bd->bi_memstart = 0;
  318. bd->bi_memsize = (8 * 1024 * 1024);
  319. bd->bi_intfreq = 40000000;
  320. bd->bi_busfreq = 40000000;
  321. }
  322. #endif /* FADS */
  323. #ifdef CONFIG_8260
  324. /* Compute 8260 clock values if the rom doesn't provide them.
  325.  * We can't compute the internal core frequency (I don't know how to
  326.  * do that).
  327.  */
  328. static void
  329. clk_8260(bd_t *bd)
  330. {
  331. uint scmr, vco_out, clkin;
  332. uint plldf, pllmf, busdf, brgdf, cpmdf;
  333. volatile immap_t *ip;
  334. ip = (immap_t *)IMAP_ADDR;
  335. scmr = ip->im_clkrst.car_scmr;
  336. /* The clkin is always bus frequency.
  337. */
  338. clkin = bd->bi_busfreq;
  339. /* Collect the bits from the scmr.
  340. */
  341. plldf = (scmr >> 12) & 1;
  342. pllmf = scmr & 0xfff;
  343. cpmdf = (scmr >> 16) & 0x0f;
  344. busdf = (scmr >> 20) & 0x0f;
  345. /* This is arithmetic from the 8260 manual.
  346. */
  347. vco_out = clkin / (plldf + 1);
  348. vco_out *= 2 * (pllmf + 1);
  349. bd->bi_vco = vco_out; /* Save for later */
  350. bd->bi_cpmfreq = vco_out / 2; /* CPM Freq, in MHz */
  351. /* Set Baud rate divisor.  The power up default is divide by 16,
  352.  * but we set it again here in case it was changed.
  353.  */
  354. ip->im_clkrst.car_sccr = 1; /* DIV 16 BRG */
  355. bd->bi_brgfreq = vco_out / 16;
  356. }
  357. #endif
  358. #ifdef CONFIG_EST8260
  359. void
  360. embed_config(bd_t **bdp)
  361. {
  362. u_char *cp;
  363. int i;
  364. bd_t *bd;
  365. bd = *bdp;
  366. #if 0
  367. /* This is actually provided by my boot rom.  I have it
  368.  * here for those people that may load the kernel with
  369.  * a JTAG/COP tool and not the rom monitor.
  370.  */
  371. bd->bi_baudrate = 115200;
  372. bd->bi_intfreq = 200000000;
  373. bd->bi_busfreq = 66666666;
  374. bd->bi_cpmfreq = 66666666;
  375. bd->bi_brgfreq = 33333333;
  376. bd->bi_memsize = 16 * 1024 * 1024;
  377. #else
  378. /* The boot rom passes these to us in MHz.  Linux now expects
  379.  * them to be in Hz.
  380.  */
  381. bd->bi_intfreq *= 1000000;
  382. bd->bi_busfreq *= 1000000;
  383. bd->bi_cpmfreq *= 1000000;
  384. bd->bi_brgfreq *= 1000000;
  385. #endif
  386. cp = (u_char *)def_enet_addr;
  387. for (i=0; i<6; i++) {
  388. bd->bi_enetaddr[i] = *cp++;
  389. }
  390. }
  391. #endif /* EST8260 */
  392. #ifdef CONFIG_SBS8260
  393. void
  394. embed_config(bd_t **bdp)
  395. {
  396. u_char *cp;
  397. int i;
  398. bd_t *bd;
  399. /* This should provided by the boot rom.
  400.  */
  401. bd = &bdinfo;
  402. *bdp = bd;
  403. bd->bi_baudrate = 9600;
  404. bd->bi_memsize = 64 * 1024 * 1024;
  405. /* Set all of the clocks.  We have to know the speed of the
  406.  * external clock.  The development board had 66 MHz.
  407.  */
  408. bd->bi_busfreq = 66666666;
  409. clk_8260(bd);
  410. /* I don't know how to compute this yet.
  411. */
  412. bd->bi_intfreq = 133000000;
  413. cp = (u_char *)def_enet_addr;
  414. for (i=0; i<6; i++) {
  415. bd->bi_enetaddr[i] = *cp++;
  416. }
  417. }
  418. #endif /* SBS8260 */
  419. #ifdef CONFIG_RPX6
  420. void
  421. embed_config(bd_t **bdp)
  422. {
  423. u_char *cp, *keyvals;
  424. int i;
  425. bd_t *bd;
  426. keyvals = (u_char *)*bdp;
  427. bd = &bdinfo;
  428. *bdp = bd;
  429. /* This is almost identical to the RPX-Lite/Classic functions
  430.  * on the 8xx boards.  It would be nice to have a key lookup
  431.  * function in a string, but the format of all of the fields
  432.  * is slightly different.
  433.  */
  434. cp = keyvals;
  435. for (;;) {
  436. if (*cp == 'E') {
  437. cp++;
  438. if (*cp == 'A') {
  439. cp += 2;
  440. rpx_eth(bd, cp);
  441. }
  442. }
  443. if (*cp == 'S') {
  444. cp++;
  445. if (*cp == 'B') {
  446. cp += 2;
  447. bd->bi_baudrate = rpx_baseten(cp);
  448. }
  449. }
  450. if (*cp == 'D') {
  451. cp++;
  452. if (*cp == '1') {
  453. cp += 2;
  454. bd->bi_memsize = rpx_baseten(cp) * 1024 * 1024;
  455. }
  456. }
  457. if (*cp == 'X') {
  458. cp++;
  459. if (*cp == 'T') {
  460. cp += 2;
  461. bd->bi_busfreq = rpx_baseten(cp);
  462. }
  463. }
  464. if (*cp == 'N') {
  465. cp++;
  466. if (*cp == 'V') {
  467. cp += 2;
  468. bd->bi_nvsize = rpx_baseten(cp) * 1024 * 1024;
  469. }
  470. }
  471. /* Scan to the end of the record.
  472. */
  473. while ((*cp != 'n') && (*cp != 0xff))
  474. cp++;
  475. /* If the next character is a 0 or ff, we are done.
  476. */
  477. cp++;
  478. if ((*cp == 0) || (*cp == 0xff))
  479. break;
  480. }
  481. bd->bi_memstart = 0;
  482. /* The memory size includes both the 60x and local bus DRAM.
  483.  * I don't want to use the local bus DRAM for real memory,
  484.  * so subtract it out.  It would be nice if they were separate
  485.  * keys.
  486.  */
  487. bd->bi_memsize -= 32 * 1024 * 1024;
  488. /* Set all of the clocks.  We have to know the speed of the
  489.  * external clock.
  490.  */
  491. clk_8260(bd);
  492. /* I don't know how to compute this yet.
  493. */
  494. bd->bi_intfreq = 200000000;
  495. }
  496. #endif /* RPX6 for testing */
  497. #ifdef CONFIG_ADS8260
  498. void
  499. embed_config(bd_t **bdp)
  500. {
  501. u_char *cp;
  502. int i;
  503. bd_t *bd;
  504. /* This should provided by the boot rom.
  505.  */
  506. bd = &bdinfo;
  507. *bdp = bd;
  508. bd->bi_baudrate = 9600;
  509. bd->bi_memsize = 16 * 1024 * 1024;
  510. /* Set all of the clocks.  We have to know the speed of the
  511.  * external clock.  The development board had 66 MHz.
  512.  */
  513. bd->bi_busfreq = 66666666;
  514. clk_8260(bd);
  515. /* I don't know how to compute this yet.
  516. */
  517. bd->bi_intfreq = 200000000;
  518. cp = (u_char *)def_enet_addr;
  519. for (i=0; i<6; i++) {
  520. bd->bi_enetaddr[i] = *cp++;
  521. }
  522. }
  523. #endif /* ADS8260 */
  524. #ifdef CONFIG_WILLOW
  525. void
  526. embed_config(bd_t **bdp)
  527. {
  528. u_char *cp;
  529. int i;
  530. bd_t *bd;
  531. /* Willow has Open Firmware....I should learn how to get this
  532.  * information from it.
  533.  */
  534. bd = &bdinfo;
  535. *bdp = bd;
  536. bd->bi_baudrate = 9600;
  537. bd->bi_memsize = 32 * 1024 * 1024;
  538. /* Set all of the clocks.  We have to know the speed of the
  539.  * external clock.  The development board had 66 MHz.
  540.  */
  541. bd->bi_busfreq = 66666666;
  542. clk_8260(bd);
  543. /* I don't know how to compute this yet.
  544. */
  545. bd->bi_intfreq = 200000000;
  546. cp = (u_char *)def_enet_addr;
  547. for (i=0; i<6; i++) {
  548. bd->bi_enetaddr[i] = *cp++;
  549. }
  550. }
  551. #endif /* WILLOW */
  552. #ifdef CONFIG_TREEBOOT
  553. /* This could possibly work for all treeboot roms.
  554. */
  555. #define BOARD_INFO_VECTOR 0xFFFE0B50
  556. void
  557. embed_config(bd_t **bdp)
  558. {
  559. u_char *cp;
  560. int i;
  561. bd_t *bd, *treeboot_bd;
  562. bd_t *(*get_board_info)(void) =
  563.     (bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR);
  564. #if !defined(CONFIG_STB03xxx)
  565. volatile emac_t *emacp;
  566. emacp = (emac_t *)EMAC0_BASE;  /* assume 1st emac - armin */
  567. /* shut down the Ethernet controller that the boot rom
  568.  * sometimes leaves running.
  569.  */
  570. mtdcr(DCRN_MALCR, MALCR_MMSR);                /* 1st reset MAL */
  571. while (mfdcr(DCRN_MALCR) & MALCR_MMSR) {};    /* wait for the reset */
  572. emacp->em0mr0 = 0x20000000;        /* then reset EMAC */
  573. eieio();
  574. #endif
  575. bd = &bdinfo;
  576. *bdp = bd;
  577. if ((treeboot_bd = get_board_info()) != NULL) {
  578. memcpy(bd, treeboot_bd, sizeof(bd_t));
  579. }
  580. else {
  581. /* Hmmm...better try to stuff some defaults.
  582. */
  583. bd->bi_memsize = 16 * 1024 * 1024;
  584. cp = (u_char *)def_enet_addr;
  585. for (i=0; i<6; i++) {
  586. /* I should probably put different ones here,
  587.  * hopefully only one is used.
  588.  */
  589. bd->BD_EMAC_ADDR(0,i) = *cp;
  590. #ifdef CONFIG_PCI
  591. bd->bi_pci_enetaddr[i] = *cp++;
  592. #endif
  593. }
  594. bd->bi_intfreq = 200000000;
  595. bd->bi_busfreq = 100000000;
  596. #ifdef CONFIG_PCI
  597. bd->bi_pci_busfreq = 66666666;
  598. #endif
  599. /* Yeah, this look weird, but on Redwood 4 they are
  600.  * different object in the structure.  When RW5 uses
  601.  * OpenBIOS, it requires a special value.
  602.  */
  603. #ifdef CONFIG_REDWOOD_5
  604. bd->bi_intfreq = 200 * 1000 * 1000;
  605. bd->bi_busfreq = 0;
  606. bd->bi_tbfreq = 27 * 1000 * 1000;
  607. #elif CONFIG_REDWOOD_4
  608. bd->bi_tbfreq = bd->bi_intfreq;
  609. #endif
  610. }
  611. }
  612. #endif
  613. #ifdef CONFIG_EP405
  614. void
  615. embed_config(bd_t **bdp)
  616. {
  617. u_char *cp;
  618. bd_t *bd;
  619. bd = &bdinfo;
  620. *bdp = bd;
  621. #if 1
  622.         cp = (u_char *)0xF0000EE0;
  623.         for (;;) {
  624.                 if (*cp == 'E') {
  625.                         cp++;
  626.                         if (*cp == 'A') {
  627.                                   cp += 2;
  628.                                   rpx_eth(bd, cp);
  629.                         }
  630.          }
  631.           if (*cp == 'D') {
  632.                          cp++;
  633.                          if (*cp == '1') {
  634.                                 cp += 2;
  635.                                 rpx_memsize(bd, cp);
  636.                          }
  637.                  }
  638. while ((*cp != 'n') && (*cp != 0xff))
  639.       cp++;
  640.                 cp++;
  641.                 if ((*cp == 0) || (*cp == 0xff))
  642.                    break;
  643.        }
  644. bd->bi_intfreq   = 200000000;
  645. bd->bi_busfreq   = 100000000;
  646. bd->bi_pci_busfreq= 33000000 ;
  647. #else
  648. bd->bi_memsize   = 64000000;
  649. bd->bi_intfreq   = 200000000;
  650. bd->bi_busfreq   = 100000000;
  651. bd->bi_pci_busfreq= 33000000 ;
  652. #endif
  653. }
  654. #endif