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