2005-04-17 06:20:36 +08:00
|
|
|
/*
|
|
|
|
* 2004-2005 (c) MontaVista, Software, Inc. This file is licensed under
|
|
|
|
* the terms of the GNU General Public License version 2. This program
|
|
|
|
* is licensed "as is" without any warranty of any kind, whether express
|
|
|
|
* or implied.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/types.h>
|
|
|
|
#include <linux/config.h>
|
|
|
|
#include <linux/string.h>
|
|
|
|
#include <linux/ctype.h>
|
|
|
|
#include <asm/ppcboot.h>
|
|
|
|
#include <asm/ibm4xx.h>
|
|
|
|
|
|
|
|
extern unsigned long decompress_kernel(unsigned long load_addr, int num_words,
|
|
|
|
unsigned long cksum);
|
|
|
|
|
|
|
|
/* We need to make sure that this is before the images to ensure
|
|
|
|
* that it's in a mapped location. - Tom */
|
|
|
|
bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
|
|
|
|
bd_t *hold_residual = &hold_resid_buf;
|
|
|
|
|
|
|
|
/* String functions lifted from lib/vsprintf.c and lib/ctype.c */
|
|
|
|
unsigned char _ctype[] = {
|
|
|
|
_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
|
|
|
|
_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
|
|
|
|
_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
|
|
|
|
_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
|
|
|
|
_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
|
|
|
|
_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
|
|
|
|
_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
|
|
|
|
_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
|
|
|
|
_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
|
|
|
|
_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
|
|
|
|
_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
|
|
|
|
_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
|
|
|
|
_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
|
|
|
|
_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
|
|
|
|
_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
|
|
|
|
_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
|
|
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
|
|
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
|
|
|
|
_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
|
|
|
|
_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
|
|
|
|
_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
|
|
|
|
_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
|
|
|
|
_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
|
|
|
|
_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* simple_strtoull - convert a string to an unsigned long long
|
|
|
|
* @cp: The start of the string
|
|
|
|
* @endp: A pointer to the end of the parsed string will be placed here
|
|
|
|
* @base: The number base to use
|
|
|
|
*/
|
|
|
|
unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
|
|
|
|
{
|
|
|
|
unsigned long long result = 0,value;
|
|
|
|
|
|
|
|
if (!base) {
|
|
|
|
base = 10;
|
|
|
|
if (*cp == '0') {
|
|
|
|
base = 8;
|
|
|
|
cp++;
|
|
|
|
if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
|
|
|
|
cp++;
|
|
|
|
base = 16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (base == 16) {
|
|
|
|
if (cp[0] == '0' && toupper(cp[1]) == 'X')
|
|
|
|
cp += 2;
|
|
|
|
}
|
|
|
|
while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
|
|
|
|
? toupper(*cp) : *cp)-'A'+10) < base) {
|
|
|
|
result = result*base + value;
|
|
|
|
cp++;
|
|
|
|
}
|
|
|
|
if (endp)
|
|
|
|
*endp = (char *)cp;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
|
|
|
load_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
|
|
|
|
void *ign1, void *ign2)
|
|
|
|
{
|
|
|
|
unsigned long long mac64;
|
|
|
|
|
|
|
|
decompress_kernel(load_addr, num_words, cksum);
|
|
|
|
|
|
|
|
mac64 = simple_strtoull((char *)PIBS_MAC_BASE, 0, 16);
|
|
|
|
memcpy(hold_residual->bi_enetaddr, (char *)&mac64+2, 6);
|
2005-08-01 13:34:52 +08:00
|
|
|
#if defined(CONFIG_440GX) || defined(CONFIG_440EP)
|
2005-04-17 06:20:36 +08:00
|
|
|
mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET), 0, 16);
|
|
|
|
memcpy(hold_residual->bi_enet1addr, (char *)&mac64+2, 6);
|
2005-08-01 13:34:52 +08:00
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_440GX
|
2005-04-17 06:20:36 +08:00
|
|
|
mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET*2), 0, 16);
|
|
|
|
memcpy(hold_residual->bi_enet2addr, (char *)&mac64+2, 6);
|
|
|
|
mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET*3), 0, 16);
|
|
|
|
memcpy(hold_residual->bi_enet3addr, (char *)&mac64+2, 6);
|
|
|
|
#endif
|
|
|
|
return (void *)hold_residual;
|
|
|
|
}
|