Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[pandora-kernel.git] / arch / ppc / boot / simple / pibs.c
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
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);
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 }