pibs.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * 2004-2005 (c) MontaVista, Software, Inc. This file is licensed under
  3. * the terms of the GNU General Public License version 2. This program
  4. * is licensed "as is" without any warranty of any kind, whether express
  5. * or implied.
  6. */
  7. #include <linux/types.h>
  8. #include <linux/config.h>
  9. #include <linux/string.h>
  10. #include <linux/ctype.h>
  11. #include <asm/ppcboot.h>
  12. #include <asm/ibm4xx.h>
  13. extern unsigned long decompress_kernel(unsigned long load_addr, int num_words,
  14. unsigned long cksum);
  15. /* We need to make sure that this is before the images to ensure
  16. * that it's in a mapped location. - Tom */
  17. bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
  18. bd_t *hold_residual = &hold_resid_buf;
  19. /* String functions lifted from lib/vsprintf.c and lib/ctype.c */
  20. unsigned char _ctype[] = {
  21. _C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
  22. _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
  23. _C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
  24. _C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
  25. _S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
  26. _P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
  27. _D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
  28. _D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
  29. _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
  30. _U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
  31. _U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
  32. _U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
  33. _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
  34. _L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
  35. _L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
  36. _L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
  37. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
  38. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
  39. _S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
  40. _P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
  41. _U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
  42. _U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
  43. _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
  44. _L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
  45. /**
  46. * simple_strtoull - convert a string to an unsigned long long
  47. * @cp: The start of the string
  48. * @endp: A pointer to the end of the parsed string will be placed here
  49. * @base: The number base to use
  50. */
  51. unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
  52. {
  53. unsigned long long result = 0,value;
  54. if (!base) {
  55. base = 10;
  56. if (*cp == '0') {
  57. base = 8;
  58. cp++;
  59. if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
  60. cp++;
  61. base = 16;
  62. }
  63. }
  64. } else if (base == 16) {
  65. if (cp[0] == '0' && toupper(cp[1]) == 'X')
  66. cp += 2;
  67. }
  68. while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
  69. ? toupper(*cp) : *cp)-'A'+10) < base) {
  70. result = result*base + value;
  71. cp++;
  72. }
  73. if (endp)
  74. *endp = (char *)cp;
  75. return result;
  76. }
  77. void *
  78. load_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
  79. void *ign1, void *ign2)
  80. {
  81. unsigned long long mac64;
  82. decompress_kernel(load_addr, num_words, cksum);
  83. mac64 = simple_strtoull((char *)PIBS_MAC_BASE, 0, 16);
  84. memcpy(hold_residual->bi_enetaddr, (char *)&mac64+2, 6);
  85. #if defined(CONFIG_440GX) || defined(CONFIG_440EP)
  86. mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET), 0, 16);
  87. memcpy(hold_residual->bi_enet1addr, (char *)&mac64+2, 6);
  88. #endif
  89. #ifdef CONFIG_440GX
  90. mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET*2), 0, 16);
  91. memcpy(hold_residual->bi_enet2addr, (char *)&mac64+2, 6);
  92. mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET*3), 0, 16);
  93. memcpy(hold_residual->bi_enet3addr, (char *)&mac64+2, 6);
  94. #endif
  95. return (void *)hold_residual;
  96. }