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>
9#include <linux/string.h>
10#include <linux/ctype.h>
11#include <asm/ppcboot.h>
12#include <asm/ibm4xx.h>
13
14extern 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 */
19bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
20bd_t *hold_residual = &hold_resid_buf;
21
22/* String functions lifted from lib/vsprintf.c and lib/ctype.c */
23unsigned 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 */
400,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,		/* 128-143 */
410,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 */
55unsigned 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
83void *
84load_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);
93#if defined(CONFIG_440GX) || defined(CONFIG_440EP)
94	mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET), 0, 16);
95	memcpy(hold_residual->bi_enet1addr, (char *)&mac64+2, 6);
96#endif
97#ifdef CONFIG_440GX
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}
105