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