diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/ppc/boot |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/ppc/boot')
85 files changed, 13219 insertions, 0 deletions
diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile new file mode 100644 index 000000000000..995f89bb049c --- /dev/null +++ b/arch/ppc/boot/Makefile | |||
@@ -0,0 +1,34 @@ | |||
1 | # | ||
2 | # arch/ppc/boot/Makefile | ||
3 | # | ||
4 | # This file is subject to the terms and conditions of the GNU General Public | ||
5 | # License. See the file "COPYING" in the main directory of this archive | ||
6 | # for more details. | ||
7 | # | ||
8 | # Copyright (C) 1994 by Linus Torvalds | ||
9 | # Adapted for PowerPC by Gary Thomas | ||
10 | # modified by Cort (cort@cs.nmt.edu) | ||
11 | # | ||
12 | |||
13 | CFLAGS += -fno-builtin -D__BOOTER__ -Iarch/$(ARCH)/boot/include | ||
14 | HOSTCFLAGS += -Iarch/$(ARCH)/boot/include | ||
15 | |||
16 | BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd | ||
17 | |||
18 | bootdir-y := simple | ||
19 | bootdir-$(CONFIG_PPC_OF) += openfirmware | ||
20 | subdir-y := lib common images | ||
21 | subdir-$(CONFIG_PPC_OF) += of1275 | ||
22 | |||
23 | # for cleaning | ||
24 | subdir- += simple openfirmware | ||
25 | |||
26 | hostprogs-y := $(addprefix utils/, addnote mknote hack-coff mkprep mkbugboot mktree) | ||
27 | |||
28 | .PHONY: $(BOOT_TARGETS) $(bootdir-y) | ||
29 | |||
30 | $(BOOT_TARGETS): $(bootdir-y) | ||
31 | |||
32 | $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ | ||
33 | $(addprefix $(obj)/,$(hostprogs-y)) | ||
34 | $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS) | ||
diff --git a/arch/ppc/boot/common/Makefile b/arch/ppc/boot/common/Makefile new file mode 100644 index 000000000000..f88d647d5dd4 --- /dev/null +++ b/arch/ppc/boot/common/Makefile | |||
@@ -0,0 +1,13 @@ | |||
1 | # | ||
2 | # arch/ppc/boot/common/Makefile | ||
3 | # | ||
4 | # This file is subject to the terms and conditions of the GNU General Public | ||
5 | # License. See the file "COPYING" in the main directory of this archive | ||
6 | # for more details. | ||
7 | # | ||
8 | # Tom Rini January 2001 | ||
9 | # | ||
10 | |||
11 | lib-y := string.o util.o misc-common.o \ | ||
12 | serial_stub.o bootinfo.o | ||
13 | lib-$(CONFIG_SERIAL_8250_CONSOLE) += ns16550.o | ||
diff --git a/arch/ppc/boot/common/bootinfo.c b/arch/ppc/boot/common/bootinfo.c new file mode 100644 index 000000000000..9c6e528940e9 --- /dev/null +++ b/arch/ppc/boot/common/bootinfo.c | |||
@@ -0,0 +1,70 @@ | |||
1 | /* | ||
2 | * arch/ppc/common/bootinfo.c | ||
3 | * | ||
4 | * General bootinfo record utilities | ||
5 | * Author: Randy Vinson <rvinson@mvista.com> | ||
6 | * | ||
7 | * 2002 (c) MontaVista Software, Inc. This file is licensed under the terms | ||
8 | * of the GNU General Public License version 2. This program is licensed | ||
9 | * "as is" without any warranty of any kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | #include <linux/string.h> | ||
14 | #include <asm/bootinfo.h> | ||
15 | |||
16 | #include "nonstdio.h" | ||
17 | |||
18 | static struct bi_record * birec = NULL; | ||
19 | |||
20 | static struct bi_record * | ||
21 | __bootinfo_build(struct bi_record *rec, unsigned long tag, unsigned long size, | ||
22 | void *data) | ||
23 | { | ||
24 | /* set the tag */ | ||
25 | rec->tag = tag; | ||
26 | |||
27 | /* if the caller has any data, copy it */ | ||
28 | if (size) | ||
29 | memcpy(rec->data, (char *)data, size); | ||
30 | |||
31 | /* set the record size */ | ||
32 | rec->size = sizeof(struct bi_record) + size; | ||
33 | |||
34 | /* advance to the next available space */ | ||
35 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
36 | |||
37 | return rec; | ||
38 | } | ||
39 | |||
40 | void | ||
41 | bootinfo_init(struct bi_record *rec) | ||
42 | { | ||
43 | |||
44 | /* save start of birec area */ | ||
45 | birec = rec; | ||
46 | |||
47 | /* create an empty list */ | ||
48 | rec = __bootinfo_build(rec, BI_FIRST, 0, NULL); | ||
49 | (void) __bootinfo_build(rec, BI_LAST, 0, NULL); | ||
50 | |||
51 | } | ||
52 | |||
53 | void | ||
54 | bootinfo_append(unsigned long tag, unsigned long size, void * data) | ||
55 | { | ||
56 | |||
57 | struct bi_record *rec = birec; | ||
58 | |||
59 | /* paranoia */ | ||
60 | if ((rec == NULL) || (rec->tag != BI_FIRST)) | ||
61 | return; | ||
62 | |||
63 | /* find the last entry in the list */ | ||
64 | while (rec->tag != BI_LAST) | ||
65 | rec = (struct bi_record *)((ulong)rec + rec->size); | ||
66 | |||
67 | /* overlay BI_LAST record with new one and tag on a new BI_LAST */ | ||
68 | rec = __bootinfo_build(rec, tag, size, data); | ||
69 | (void) __bootinfo_build(rec, BI_LAST, 0, NULL); | ||
70 | } | ||
diff --git a/arch/ppc/boot/common/crt0.S b/arch/ppc/boot/common/crt0.S new file mode 100644 index 000000000000..4d31b824bbd1 --- /dev/null +++ b/arch/ppc/boot/common/crt0.S | |||
@@ -0,0 +1,81 @@ | |||
1 | /* Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au> | ||
2 | * Initial Power Macintosh COFF version. | ||
3 | * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> | ||
4 | * Modifications for IBM PowerPC 400-class processor evaluation | ||
5 | * boards. | ||
6 | * | ||
7 | * Module name: crt0.S | ||
8 | * | ||
9 | * Description: | ||
10 | * Boot loader execution entry point. Clears out .bss section as per | ||
11 | * ANSI C requirements. Invalidates and flushes the caches over the | ||
12 | * range covered by the boot loader's .text section. Sets up a stack | ||
13 | * below the .text section entry point. | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License | ||
17 | * as published by the Free Software Foundation; either version | ||
18 | * 2 of the License, or (at your option) any later version. | ||
19 | */ | ||
20 | |||
21 | #include <linux/config.h> | ||
22 | #include <asm/ppc_asm.h> | ||
23 | |||
24 | .text | ||
25 | |||
26 | .globl _start | ||
27 | _start: | ||
28 | #ifdef XCOFF | ||
29 | .long __start,0,0 | ||
30 | |||
31 | .globl __start | ||
32 | __start: | ||
33 | #endif | ||
34 | |||
35 | ## Flush and invalidate the caches for the range in memory covering | ||
36 | ## the .text section of the boot loader | ||
37 | |||
38 | lis r9,_start@h # r9 = &_start | ||
39 | lis r8,_etext@ha # | ||
40 | addi r8,r8,_etext@l # r8 = &_etext | ||
41 | 3: dcbf r0,r9 # Flush the data cache | ||
42 | icbi r0,r9 # Invalidate the instruction cache | ||
43 | addi r9,r9,0x10 # Increment by one cache line | ||
44 | cmplw cr0,r9,r8 # Are we at the end yet? | ||
45 | blt 3b # No, keep flushing and invalidating | ||
46 | sync # sync ; isync after flushing the icache | ||
47 | isync | ||
48 | |||
49 | ## Clear out the BSS as per ANSI C requirements | ||
50 | |||
51 | lis r7,_end@ha | ||
52 | addi r7,r7,_end@l # r7 = &_end | ||
53 | lis r8,__bss_start@ha # | ||
54 | addi r8,r8,__bss_start@l # r8 = &_bss_start | ||
55 | |||
56 | ## Determine how large an area, in number of words, to clear | ||
57 | |||
58 | subf r7,r8,r7 # r7 = &_end - &_bss_start + 1 | ||
59 | addi r7,r7,3 # r7 += 3 | ||
60 | srwi. r7,r7,2 # r7 = size in words. | ||
61 | beq 2f # If the size is zero, do not bother | ||
62 | addi r8,r8,-4 # r8 -= 4 | ||
63 | mtctr r7 # SPRN_CTR = number of words to clear | ||
64 | li r0,0 # r0 = 0 | ||
65 | 1: stwu r0,4(r8) # Clear out a word | ||
66 | bdnz 1b # If we are not done yet, keep clearing | ||
67 | 2: | ||
68 | |||
69 | #ifdef CONFIG_40x | ||
70 | ## Set up the stack | ||
71 | |||
72 | lis r9,_start@h # r9 = &_start (text section entry) | ||
73 | ori r9,r9,_start@l | ||
74 | subi r1,r9,64 # Start the stack 64 bytes below _start | ||
75 | clrrwi r1,r1,4 # Make sure it is aligned on 16 bytes. | ||
76 | li r0,0 | ||
77 | stwu r0,-16(r1) | ||
78 | mtlr r9 | ||
79 | #endif | ||
80 | |||
81 | b start # All done, start the real work. | ||
diff --git a/arch/ppc/boot/common/misc-common.c b/arch/ppc/boot/common/misc-common.c new file mode 100644 index 000000000000..e79e6b3f276e --- /dev/null +++ b/arch/ppc/boot/common/misc-common.c | |||
@@ -0,0 +1,553 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/common/misc-common.c | ||
3 | * | ||
4 | * Misc. bootloader code (almost) all platforms can use | ||
5 | * | ||
6 | * Author: Johnnie Peters <jpeters@mvista.com> | ||
7 | * Editor: Tom Rini <trini@mvista.com> | ||
8 | * | ||
9 | * Derived from arch/ppc/boot/prep/misc.c | ||
10 | * | ||
11 | * 2000-2001 (c) MontaVista, Software, Inc. This file is licensed under | ||
12 | * the terms of the GNU General Public License version 2. This program | ||
13 | * is licensed "as is" without any warranty of any kind, whether express | ||
14 | * or implied. | ||
15 | */ | ||
16 | |||
17 | #include <stdarg.h> /* for va_ bits */ | ||
18 | #include <linux/config.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/zlib.h> | ||
21 | #include "nonstdio.h" | ||
22 | |||
23 | /* If we're on a PReP, assume we have a keyboard controller | ||
24 | * Also note, if we're not PReP, we assume you are a serial | ||
25 | * console - Tom */ | ||
26 | #if defined(CONFIG_PPC_PREP) && defined(CONFIG_VGA_CONSOLE) | ||
27 | extern void cursor(int x, int y); | ||
28 | extern void scroll(void); | ||
29 | extern char *vidmem; | ||
30 | extern int lines, cols; | ||
31 | extern int orig_x, orig_y; | ||
32 | extern int keyb_present; | ||
33 | extern int CRT_tstc(void); | ||
34 | extern int CRT_getc(void); | ||
35 | #else | ||
36 | int cursor(int x, int y) {return 0;} | ||
37 | void scroll(void) {} | ||
38 | char vidmem[1]; | ||
39 | #define lines 0 | ||
40 | #define cols 0 | ||
41 | int orig_x = 0; | ||
42 | int orig_y = 0; | ||
43 | #define keyb_present 0 | ||
44 | int CRT_tstc(void) {return 0;} | ||
45 | int CRT_getc(void) {return 0;} | ||
46 | #endif | ||
47 | |||
48 | extern char *avail_ram; | ||
49 | extern char *end_avail; | ||
50 | extern char _end[]; | ||
51 | |||
52 | void puts(const char *); | ||
53 | void putc(const char c); | ||
54 | void puthex(unsigned long val); | ||
55 | void gunzip(void *, int, unsigned char *, int *); | ||
56 | static int _cvt(unsigned long val, char *buf, long radix, char *digits); | ||
57 | |||
58 | void _vprintk(void(*putc)(const char), const char *fmt0, va_list ap); | ||
59 | unsigned char *ISA_io = NULL; | ||
60 | |||
61 | #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \ | ||
62 | || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ | ||
63 | || defined(CONFIG_SERIAL_MPSC_CONSOLE) | ||
64 | extern unsigned long com_port; | ||
65 | |||
66 | extern int serial_tstc(unsigned long com_port); | ||
67 | extern unsigned char serial_getc(unsigned long com_port); | ||
68 | extern void serial_putc(unsigned long com_port, unsigned char c); | ||
69 | #endif | ||
70 | |||
71 | void pause(void) | ||
72 | { | ||
73 | puts("pause\n"); | ||
74 | } | ||
75 | |||
76 | void exit(void) | ||
77 | { | ||
78 | puts("exit\n"); | ||
79 | while(1); | ||
80 | } | ||
81 | |||
82 | int tstc(void) | ||
83 | { | ||
84 | #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \ | ||
85 | || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ | ||
86 | || defined(CONFIG_SERIAL_MPSC_CONSOLE) | ||
87 | if(keyb_present) | ||
88 | return (CRT_tstc() || serial_tstc(com_port)); | ||
89 | else | ||
90 | return (serial_tstc(com_port)); | ||
91 | #else | ||
92 | return CRT_tstc(); | ||
93 | #endif | ||
94 | } | ||
95 | |||
96 | int getc(void) | ||
97 | { | ||
98 | while (1) { | ||
99 | #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \ | ||
100 | || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ | ||
101 | || defined(CONFIG_SERIAL_MPSC_CONSOLE) | ||
102 | if (serial_tstc(com_port)) | ||
103 | return (serial_getc(com_port)); | ||
104 | #endif /* serial console */ | ||
105 | if (keyb_present) | ||
106 | if(CRT_tstc()) | ||
107 | return (CRT_getc()); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | void | ||
112 | putc(const char c) | ||
113 | { | ||
114 | int x,y; | ||
115 | |||
116 | #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \ | ||
117 | || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ | ||
118 | || defined(CONFIG_SERIAL_MPSC_CONSOLE) | ||
119 | serial_putc(com_port, c); | ||
120 | if ( c == '\n' ) | ||
121 | serial_putc(com_port, '\r'); | ||
122 | #endif /* serial console */ | ||
123 | |||
124 | x = orig_x; | ||
125 | y = orig_y; | ||
126 | |||
127 | if ( c == '\n' ) { | ||
128 | x = 0; | ||
129 | if ( ++y >= lines ) { | ||
130 | scroll(); | ||
131 | y--; | ||
132 | } | ||
133 | } else if (c == '\r') { | ||
134 | x = 0; | ||
135 | } else if (c == '\b') { | ||
136 | if (x > 0) { | ||
137 | x--; | ||
138 | } | ||
139 | } else { | ||
140 | vidmem [ ( x + cols * y ) * 2 ] = c; | ||
141 | if ( ++x >= cols ) { | ||
142 | x = 0; | ||
143 | if ( ++y >= lines ) { | ||
144 | scroll(); | ||
145 | y--; | ||
146 | } | ||
147 | } | ||
148 | } | ||
149 | |||
150 | cursor(x, y); | ||
151 | |||
152 | orig_x = x; | ||
153 | orig_y = y; | ||
154 | } | ||
155 | |||
156 | void puts(const char *s) | ||
157 | { | ||
158 | int x,y; | ||
159 | char c; | ||
160 | |||
161 | x = orig_x; | ||
162 | y = orig_y; | ||
163 | |||
164 | while ( ( c = *s++ ) != '\0' ) { | ||
165 | #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \ | ||
166 | || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ | ||
167 | || defined(CONFIG_SERIAL_MPSC_CONSOLE) | ||
168 | serial_putc(com_port, c); | ||
169 | if ( c == '\n' ) serial_putc(com_port, '\r'); | ||
170 | #endif /* serial console */ | ||
171 | |||
172 | if ( c == '\n' ) { | ||
173 | x = 0; | ||
174 | if ( ++y >= lines ) { | ||
175 | scroll(); | ||
176 | y--; | ||
177 | } | ||
178 | } else if (c == '\b') { | ||
179 | if (x > 0) { | ||
180 | x--; | ||
181 | } | ||
182 | } else { | ||
183 | vidmem [ ( x + cols * y ) * 2 ] = c; | ||
184 | if ( ++x >= cols ) { | ||
185 | x = 0; | ||
186 | if ( ++y >= lines ) { | ||
187 | scroll(); | ||
188 | y--; | ||
189 | } | ||
190 | } | ||
191 | } | ||
192 | } | ||
193 | |||
194 | cursor(x, y); | ||
195 | |||
196 | orig_x = x; | ||
197 | orig_y = y; | ||
198 | } | ||
199 | |||
200 | void error(char *x) | ||
201 | { | ||
202 | puts("\n\n"); | ||
203 | puts(x); | ||
204 | puts("\n\n -- System halted"); | ||
205 | |||
206 | while(1); /* Halt */ | ||
207 | } | ||
208 | |||
209 | static void *zalloc(unsigned size) | ||
210 | { | ||
211 | void *p = avail_ram; | ||
212 | |||
213 | size = (size + 7) & -8; | ||
214 | avail_ram += size; | ||
215 | if (avail_ram > end_avail) { | ||
216 | puts("oops... out of memory\n"); | ||
217 | pause(); | ||
218 | } | ||
219 | return p; | ||
220 | } | ||
221 | |||
222 | #define HEAD_CRC 2 | ||
223 | #define EXTRA_FIELD 4 | ||
224 | #define ORIG_NAME 8 | ||
225 | #define COMMENT 0x10 | ||
226 | #define RESERVED 0xe0 | ||
227 | |||
228 | void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) | ||
229 | { | ||
230 | z_stream s; | ||
231 | int r, i, flags; | ||
232 | |||
233 | /* skip header */ | ||
234 | i = 10; | ||
235 | flags = src[3]; | ||
236 | if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) { | ||
237 | puts("bad gzipped data\n"); | ||
238 | exit(); | ||
239 | } | ||
240 | if ((flags & EXTRA_FIELD) != 0) | ||
241 | i = 12 + src[10] + (src[11] << 8); | ||
242 | if ((flags & ORIG_NAME) != 0) | ||
243 | while (src[i++] != 0) | ||
244 | ; | ||
245 | if ((flags & COMMENT) != 0) | ||
246 | while (src[i++] != 0) | ||
247 | ; | ||
248 | if ((flags & HEAD_CRC) != 0) | ||
249 | i += 2; | ||
250 | if (i >= *lenp) { | ||
251 | puts("gunzip: ran out of data in header\n"); | ||
252 | exit(); | ||
253 | } | ||
254 | |||
255 | /* Initialize ourself. */ | ||
256 | s.workspace = zalloc(zlib_inflate_workspacesize()); | ||
257 | r = zlib_inflateInit2(&s, -MAX_WBITS); | ||
258 | if (r != Z_OK) { | ||
259 | puts("zlib_inflateInit2 returned "); puthex(r); puts("\n"); | ||
260 | exit(); | ||
261 | } | ||
262 | s.next_in = src + i; | ||
263 | s.avail_in = *lenp - i; | ||
264 | s.next_out = dst; | ||
265 | s.avail_out = dstlen; | ||
266 | r = zlib_inflate(&s, Z_FINISH); | ||
267 | if (r != Z_OK && r != Z_STREAM_END) { | ||
268 | puts("inflate returned "); puthex(r); puts("\n"); | ||
269 | exit(); | ||
270 | } | ||
271 | *lenp = s.next_out - (unsigned char *) dst; | ||
272 | zlib_inflateEnd(&s); | ||
273 | } | ||
274 | |||
275 | void | ||
276 | puthex(unsigned long val) | ||
277 | { | ||
278 | |||
279 | unsigned char buf[10]; | ||
280 | int i; | ||
281 | for (i = 7; i >= 0; i--) | ||
282 | { | ||
283 | buf[i] = "0123456789ABCDEF"[val & 0x0F]; | ||
284 | val >>= 4; | ||
285 | } | ||
286 | buf[8] = '\0'; | ||
287 | puts(buf); | ||
288 | } | ||
289 | |||
290 | #define FALSE 0 | ||
291 | #define TRUE 1 | ||
292 | |||
293 | void | ||
294 | _printk(char const *fmt, ...) | ||
295 | { | ||
296 | va_list ap; | ||
297 | |||
298 | va_start(ap, fmt); | ||
299 | _vprintk(putc, fmt, ap); | ||
300 | va_end(ap); | ||
301 | return; | ||
302 | } | ||
303 | |||
304 | #define is_digit(c) ((c >= '0') && (c <= '9')) | ||
305 | |||
306 | void | ||
307 | _vprintk(void(*putc)(const char), const char *fmt0, va_list ap) | ||
308 | { | ||
309 | char c, sign, *cp = 0; | ||
310 | int left_prec, right_prec, zero_fill, length = 0, pad, pad_on_right; | ||
311 | char buf[32]; | ||
312 | long val; | ||
313 | while ((c = *fmt0++)) | ||
314 | { | ||
315 | if (c == '%') | ||
316 | { | ||
317 | c = *fmt0++; | ||
318 | left_prec = right_prec = pad_on_right = 0; | ||
319 | if (c == '-') | ||
320 | { | ||
321 | c = *fmt0++; | ||
322 | pad_on_right++; | ||
323 | } | ||
324 | if (c == '0') | ||
325 | { | ||
326 | zero_fill = TRUE; | ||
327 | c = *fmt0++; | ||
328 | } else | ||
329 | { | ||
330 | zero_fill = FALSE; | ||
331 | } | ||
332 | while (is_digit(c)) | ||
333 | { | ||
334 | left_prec = (left_prec * 10) + (c - '0'); | ||
335 | c = *fmt0++; | ||
336 | } | ||
337 | if (c == '.') | ||
338 | { | ||
339 | c = *fmt0++; | ||
340 | zero_fill++; | ||
341 | while (is_digit(c)) | ||
342 | { | ||
343 | right_prec = (right_prec * 10) + (c - '0'); | ||
344 | c = *fmt0++; | ||
345 | } | ||
346 | } else | ||
347 | { | ||
348 | right_prec = left_prec; | ||
349 | } | ||
350 | sign = '\0'; | ||
351 | switch (c) | ||
352 | { | ||
353 | case 'd': | ||
354 | case 'x': | ||
355 | case 'X': | ||
356 | val = va_arg(ap, long); | ||
357 | switch (c) | ||
358 | { | ||
359 | case 'd': | ||
360 | if (val < 0) | ||
361 | { | ||
362 | sign = '-'; | ||
363 | val = -val; | ||
364 | } | ||
365 | length = _cvt(val, buf, 10, "0123456789"); | ||
366 | break; | ||
367 | case 'x': | ||
368 | length = _cvt(val, buf, 16, "0123456789abcdef"); | ||
369 | break; | ||
370 | case 'X': | ||
371 | length = _cvt(val, buf, 16, "0123456789ABCDEF"); | ||
372 | break; | ||
373 | } | ||
374 | cp = buf; | ||
375 | break; | ||
376 | case 's': | ||
377 | cp = va_arg(ap, char *); | ||
378 | length = strlen(cp); | ||
379 | break; | ||
380 | case 'c': | ||
381 | c = va_arg(ap, long /*char*/); | ||
382 | (*putc)(c); | ||
383 | continue; | ||
384 | default: | ||
385 | (*putc)('?'); | ||
386 | } | ||
387 | pad = left_prec - length; | ||
388 | if (sign != '\0') | ||
389 | { | ||
390 | pad--; | ||
391 | } | ||
392 | if (zero_fill) | ||
393 | { | ||
394 | c = '0'; | ||
395 | if (sign != '\0') | ||
396 | { | ||
397 | (*putc)(sign); | ||
398 | sign = '\0'; | ||
399 | } | ||
400 | } else | ||
401 | { | ||
402 | c = ' '; | ||
403 | } | ||
404 | if (!pad_on_right) | ||
405 | { | ||
406 | while (pad-- > 0) | ||
407 | { | ||
408 | (*putc)(c); | ||
409 | } | ||
410 | } | ||
411 | if (sign != '\0') | ||
412 | { | ||
413 | (*putc)(sign); | ||
414 | } | ||
415 | while (length-- > 0) | ||
416 | { | ||
417 | (*putc)(c = *cp++); | ||
418 | if (c == '\n') | ||
419 | { | ||
420 | (*putc)('\r'); | ||
421 | } | ||
422 | } | ||
423 | if (pad_on_right) | ||
424 | { | ||
425 | while (pad-- > 0) | ||
426 | { | ||
427 | (*putc)(c); | ||
428 | } | ||
429 | } | ||
430 | } else | ||
431 | { | ||
432 | (*putc)(c); | ||
433 | if (c == '\n') | ||
434 | { | ||
435 | (*putc)('\r'); | ||
436 | } | ||
437 | } | ||
438 | } | ||
439 | } | ||
440 | |||
441 | int | ||
442 | _cvt(unsigned long val, char *buf, long radix, char *digits) | ||
443 | { | ||
444 | char temp[80]; | ||
445 | char *cp = temp; | ||
446 | int length = 0; | ||
447 | if (val == 0) | ||
448 | { /* Special case */ | ||
449 | *cp++ = '0'; | ||
450 | } else | ||
451 | while (val) | ||
452 | { | ||
453 | *cp++ = digits[val % radix]; | ||
454 | val /= radix; | ||
455 | } | ||
456 | while (cp != temp) | ||
457 | { | ||
458 | *buf++ = *--cp; | ||
459 | length++; | ||
460 | } | ||
461 | *buf = '\0'; | ||
462 | return (length); | ||
463 | } | ||
464 | |||
465 | void | ||
466 | _dump_buf_with_offset(unsigned char *p, int s, unsigned char *base) | ||
467 | { | ||
468 | int i, c; | ||
469 | if ((unsigned int)s > (unsigned int)p) | ||
470 | { | ||
471 | s = (unsigned int)s - (unsigned int)p; | ||
472 | } | ||
473 | while (s > 0) | ||
474 | { | ||
475 | if (base) | ||
476 | { | ||
477 | _printk("%06X: ", (int)p - (int)base); | ||
478 | } else | ||
479 | { | ||
480 | _printk("%06X: ", p); | ||
481 | } | ||
482 | for (i = 0; i < 16; i++) | ||
483 | { | ||
484 | if (i < s) | ||
485 | { | ||
486 | _printk("%02X", p[i] & 0xFF); | ||
487 | } else | ||
488 | { | ||
489 | _printk(" "); | ||
490 | } | ||
491 | if ((i % 2) == 1) _printk(" "); | ||
492 | if ((i % 8) == 7) _printk(" "); | ||
493 | } | ||
494 | _printk(" |"); | ||
495 | for (i = 0; i < 16; i++) | ||
496 | { | ||
497 | if (i < s) | ||
498 | { | ||
499 | c = p[i] & 0xFF; | ||
500 | if ((c < 0x20) || (c >= 0x7F)) c = '.'; | ||
501 | } else | ||
502 | { | ||
503 | c = ' '; | ||
504 | } | ||
505 | _printk("%c", c); | ||
506 | } | ||
507 | _printk("|\n"); | ||
508 | s -= 16; | ||
509 | p += 16; | ||
510 | } | ||
511 | } | ||
512 | |||
513 | void | ||
514 | _dump_buf(unsigned char *p, int s) | ||
515 | { | ||
516 | _printk("\n"); | ||
517 | _dump_buf_with_offset(p, s, 0); | ||
518 | } | ||
519 | |||
520 | /* Very simple inb/outb routines. We declare ISA_io to be 0 above, and | ||
521 | * then modify it on platforms which need to. We do it like this | ||
522 | * because on some platforms we give inb/outb an exact location, and | ||
523 | * on others it's an offset from a given location. -- Tom | ||
524 | */ | ||
525 | |||
526 | void ISA_init(unsigned long base) | ||
527 | { | ||
528 | ISA_io = (unsigned char *)base; | ||
529 | } | ||
530 | |||
531 | void | ||
532 | outb(int port, unsigned char val) | ||
533 | { | ||
534 | /* Ensure I/O operations complete */ | ||
535 | __asm__ volatile("eieio"); | ||
536 | ISA_io[port] = val; | ||
537 | } | ||
538 | |||
539 | unsigned char | ||
540 | inb(int port) | ||
541 | { | ||
542 | /* Ensure I/O operations complete */ | ||
543 | __asm__ volatile("eieio"); | ||
544 | return (ISA_io[port]); | ||
545 | } | ||
546 | |||
547 | /* | ||
548 | * Local variables: | ||
549 | * c-indent-level: 8 | ||
550 | * c-basic-offset: 8 | ||
551 | * tab-width: 8 | ||
552 | * End: | ||
553 | */ | ||
diff --git a/arch/ppc/boot/common/ns16550.c b/arch/ppc/boot/common/ns16550.c new file mode 100644 index 000000000000..9017c547a6f6 --- /dev/null +++ b/arch/ppc/boot/common/ns16550.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * COM1 NS16550 support | ||
3 | */ | ||
4 | |||
5 | #include <linux/config.h> | ||
6 | #include <linux/types.h> | ||
7 | #include <linux/serial.h> | ||
8 | #include <linux/serial_reg.h> | ||
9 | #include <asm/serial.h> | ||
10 | |||
11 | #include "nonstdio.h" | ||
12 | #include "serial.h" | ||
13 | |||
14 | #define SERIAL_BAUD 9600 | ||
15 | |||
16 | extern unsigned long ISA_io; | ||
17 | |||
18 | static struct serial_state rs_table[RS_TABLE_SIZE] = { | ||
19 | SERIAL_PORT_DFNS /* Defined in <asm/serial.h> */ | ||
20 | }; | ||
21 | |||
22 | static int shift; | ||
23 | |||
24 | unsigned long serial_init(int chan, void *ignored) | ||
25 | { | ||
26 | unsigned long com_port; | ||
27 | unsigned char lcr, dlm; | ||
28 | |||
29 | /* We need to find out which type io we're expecting. If it's | ||
30 | * 'SERIAL_IO_PORT', we get an offset from the isa_io_base. | ||
31 | * If it's 'SERIAL_IO_MEM', we can the exact location. -- Tom */ | ||
32 | switch (rs_table[chan].io_type) { | ||
33 | case SERIAL_IO_PORT: | ||
34 | com_port = rs_table[chan].port; | ||
35 | break; | ||
36 | case SERIAL_IO_MEM: | ||
37 | com_port = (unsigned long)rs_table[chan].iomem_base; | ||
38 | break; | ||
39 | default: | ||
40 | /* We can't deal with it. */ | ||
41 | return -1; | ||
42 | } | ||
43 | |||
44 | /* How far apart the registers are. */ | ||
45 | shift = rs_table[chan].iomem_reg_shift; | ||
46 | |||
47 | /* save the LCR */ | ||
48 | lcr = inb(com_port + (UART_LCR << shift)); | ||
49 | /* Access baud rate */ | ||
50 | outb(com_port + (UART_LCR << shift), 0x80); | ||
51 | dlm = inb(com_port + (UART_DLM << shift)); | ||
52 | /* | ||
53 | * Test if serial port is unconfigured. | ||
54 | * We assume that no-one uses less than 110 baud or | ||
55 | * less than 7 bits per character these days. | ||
56 | * -- paulus. | ||
57 | */ | ||
58 | |||
59 | if ((dlm <= 4) && (lcr & 2)) | ||
60 | /* port is configured, put the old LCR back */ | ||
61 | outb(com_port + (UART_LCR << shift), lcr); | ||
62 | else { | ||
63 | /* Input clock. */ | ||
64 | outb(com_port + (UART_DLL << shift), | ||
65 | (BASE_BAUD / SERIAL_BAUD) & 0xFF); | ||
66 | outb(com_port + (UART_DLM << shift), | ||
67 | (BASE_BAUD / SERIAL_BAUD) >> 8); | ||
68 | /* 8 data, 1 stop, no parity */ | ||
69 | outb(com_port + (UART_LCR << shift), 0x03); | ||
70 | /* RTS/DTR */ | ||
71 | outb(com_port + (UART_MCR << shift), 0x03); | ||
72 | } | ||
73 | /* Clear & enable FIFOs */ | ||
74 | outb(com_port + (UART_FCR << shift), 0x07); | ||
75 | |||
76 | return (com_port); | ||
77 | } | ||
78 | |||
79 | void | ||
80 | serial_putc(unsigned long com_port, unsigned char c) | ||
81 | { | ||
82 | while ((inb(com_port + (UART_LSR << shift)) & UART_LSR_THRE) == 0) | ||
83 | ; | ||
84 | outb(com_port, c); | ||
85 | } | ||
86 | |||
87 | unsigned char | ||
88 | serial_getc(unsigned long com_port) | ||
89 | { | ||
90 | while ((inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) == 0) | ||
91 | ; | ||
92 | return inb(com_port); | ||
93 | } | ||
94 | |||
95 | int | ||
96 | serial_tstc(unsigned long com_port) | ||
97 | { | ||
98 | return ((inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) != 0); | ||
99 | } | ||
diff --git a/arch/ppc/boot/common/serial_stub.c b/arch/ppc/boot/common/serial_stub.c new file mode 100644 index 000000000000..03dfaa01fa63 --- /dev/null +++ b/arch/ppc/boot/common/serial_stub.c | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/common/serial_stub.c | ||
3 | * | ||
4 | * This is a few stub routines to make the boot code cleaner looking when | ||
5 | * there is no serial port support doesn't need to be closed, for example. | ||
6 | * | ||
7 | * Author: Tom Rini <trini@mvista.com> | ||
8 | * | ||
9 | * 2003 (c) MontaVista, Software, Inc. This file is licensed under the terms | ||
10 | * of the GNU General Public License version 2. This program is licensed "as | ||
11 | * is" without any warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | unsigned long __attribute__ ((weak)) | ||
15 | serial_init(int chan, void *ignored) | ||
16 | { | ||
17 | return 0; | ||
18 | } | ||
19 | |||
20 | void __attribute__ ((weak)) | ||
21 | serial_close(unsigned long com_port) | ||
22 | { | ||
23 | } | ||
diff --git a/arch/ppc/boot/common/string.S b/arch/ppc/boot/common/string.S new file mode 100644 index 000000000000..8016e43c4771 --- /dev/null +++ b/arch/ppc/boot/common/string.S | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | * String handling functions for PowerPC. | ||
3 | * | ||
4 | * Copyright (C) 1996 Paul Mackerras. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | #define r0 0 | ||
12 | #define r3 3 | ||
13 | #define r4 4 | ||
14 | #define r5 5 | ||
15 | #define r6 6 | ||
16 | #define r7 7 | ||
17 | #define r8 8 | ||
18 | |||
19 | .globl strlen | ||
20 | strlen: | ||
21 | addi r4,r3,-1 | ||
22 | 1: lbzu r0,1(r4) | ||
23 | cmpwi 0,r0,0 | ||
24 | bne 1b | ||
25 | subf r3,r3,r4 | ||
26 | blr | ||
27 | |||
28 | .globl memset | ||
29 | memset: | ||
30 | rlwimi r4,r4,8,16,23 | ||
31 | rlwimi r4,r4,16,0,15 | ||
32 | addi r6,r3,-4 | ||
33 | cmplwi 0,r5,4 | ||
34 | blt 7f | ||
35 | stwu r4,4(r6) | ||
36 | beqlr | ||
37 | andi. r0,r6,3 | ||
38 | add r5,r0,r5 | ||
39 | subf r6,r0,r6 | ||
40 | rlwinm r0,r5,32-2,2,31 | ||
41 | mtctr r0 | ||
42 | bdz 6f | ||
43 | 1: stwu r4,4(r6) | ||
44 | bdnz 1b | ||
45 | 6: andi. r5,r5,3 | ||
46 | 7: cmpwi 0,r5,0 | ||
47 | beqlr | ||
48 | mtctr r5 | ||
49 | addi r6,r6,3 | ||
50 | 8: stbu r4,1(r6) | ||
51 | bdnz 8b | ||
52 | blr | ||
53 | |||
54 | .globl memmove | ||
55 | memmove: | ||
56 | cmplw 0,r3,r4 | ||
57 | bgt backwards_memcpy | ||
58 | /* fall through */ | ||
59 | |||
60 | .globl memcpy | ||
61 | memcpy: | ||
62 | rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ | ||
63 | addi r6,r3,-4 | ||
64 | addi r4,r4,-4 | ||
65 | beq 2f /* if less than 8 bytes to do */ | ||
66 | andi. r0,r6,3 /* get dest word aligned */ | ||
67 | mtctr r7 | ||
68 | bne 5f | ||
69 | 1: lwz r7,4(r4) | ||
70 | lwzu r8,8(r4) | ||
71 | stw r7,4(r6) | ||
72 | stwu r8,8(r6) | ||
73 | bdnz 1b | ||
74 | andi. r5,r5,7 | ||
75 | 2: cmplwi 0,r5,4 | ||
76 | blt 3f | ||
77 | lwzu r0,4(r4) | ||
78 | addi r5,r5,-4 | ||
79 | stwu r0,4(r6) | ||
80 | 3: cmpwi 0,r5,0 | ||
81 | beqlr | ||
82 | mtctr r5 | ||
83 | addi r4,r4,3 | ||
84 | addi r6,r6,3 | ||
85 | 4: lbzu r0,1(r4) | ||
86 | stbu r0,1(r6) | ||
87 | bdnz 4b | ||
88 | blr | ||
89 | 5: subfic r0,r0,4 | ||
90 | mtctr r0 | ||
91 | 6: lbz r7,4(r4) | ||
92 | addi r4,r4,1 | ||
93 | stb r7,4(r6) | ||
94 | addi r6,r6,1 | ||
95 | bdnz 6b | ||
96 | subf r5,r0,r5 | ||
97 | rlwinm. r7,r5,32-3,3,31 | ||
98 | beq 2b | ||
99 | mtctr r7 | ||
100 | b 1b | ||
101 | |||
102 | .globl backwards_memcpy | ||
103 | backwards_memcpy: | ||
104 | rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ | ||
105 | add r6,r3,r5 | ||
106 | add r4,r4,r5 | ||
107 | beq 2f | ||
108 | andi. r0,r6,3 | ||
109 | mtctr r7 | ||
110 | bne 5f | ||
111 | 1: lwz r7,-4(r4) | ||
112 | lwzu r8,-8(r4) | ||
113 | stw r7,-4(r6) | ||
114 | stwu r8,-8(r6) | ||
115 | bdnz 1b | ||
116 | andi. r5,r5,7 | ||
117 | 2: cmplwi 0,r5,4 | ||
118 | blt 3f | ||
119 | lwzu r0,-4(r4) | ||
120 | subi r5,r5,4 | ||
121 | stwu r0,-4(r6) | ||
122 | 3: cmpwi 0,r5,0 | ||
123 | beqlr | ||
124 | mtctr r5 | ||
125 | 4: lbzu r0,-1(r4) | ||
126 | stbu r0,-1(r6) | ||
127 | bdnz 4b | ||
128 | blr | ||
129 | 5: mtctr r0 | ||
130 | 6: lbzu r7,-1(r4) | ||
131 | stbu r7,-1(r6) | ||
132 | bdnz 6b | ||
133 | subf r5,r0,r5 | ||
134 | rlwinm. r7,r5,32-3,3,31 | ||
135 | beq 2b | ||
136 | mtctr r7 | ||
137 | b 1b | ||
138 | |||
139 | .globl memcmp | ||
140 | memcmp: | ||
141 | cmpwi 0,r5,0 | ||
142 | blelr | ||
143 | mtctr r5 | ||
144 | addi r6,r3,-1 | ||
145 | addi r4,r4,-1 | ||
146 | 1: lbzu r3,1(r6) | ||
147 | lbzu r0,1(r4) | ||
148 | subf. r3,r0,r3 | ||
149 | bdnzt 2,1b | ||
150 | blr | ||
diff --git a/arch/ppc/boot/common/util.S b/arch/ppc/boot/common/util.S new file mode 100644 index 000000000000..47e641455bc5 --- /dev/null +++ b/arch/ppc/boot/common/util.S | |||
@@ -0,0 +1,293 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/common/util.S | ||
3 | * | ||
4 | * Useful bootup functions, which are more easily done in asm than C. | ||
5 | * | ||
6 | * NOTE: Be very very careful about the registers you use here. | ||
7 | * We don't follow any ABI calling convention among the | ||
8 | * assembler functions that call each other, especially early | ||
9 | * in the initialization. Please preserve at least r3 and r4 | ||
10 | * for these early functions, as they often contain information | ||
11 | * passed from boot roms into the C decompress function. | ||
12 | * | ||
13 | * Author: Tom Rini | ||
14 | * trini@mvista.com | ||
15 | * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others). | ||
16 | * | ||
17 | * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under | ||
18 | * the terms of the GNU General Public License version 2. This program | ||
19 | * is licensed "as is" without any warranty of any kind, whether express | ||
20 | * or implied. | ||
21 | */ | ||
22 | |||
23 | #include <asm/processor.h> | ||
24 | #include <asm/cache.h> | ||
25 | #include <asm/ppc_asm.h> | ||
26 | |||
27 | |||
28 | .text | ||
29 | |||
30 | #ifdef CONFIG_6xx | ||
31 | .globl disable_6xx_mmu | ||
32 | disable_6xx_mmu: | ||
33 | /* Establish default MSR value, exception prefix 0xFFF. | ||
34 | * If necessary, this function must fix up the LR if we | ||
35 | * return to a different address space once the MMU is | ||
36 | * disabled. | ||
37 | */ | ||
38 | li r8,MSR_IP|MSR_FP | ||
39 | mtmsr r8 | ||
40 | isync | ||
41 | |||
42 | /* Test for a 601 */ | ||
43 | mfpvr r10 | ||
44 | srwi r10,r10,16 | ||
45 | cmpwi 0,r10,1 /* 601 ? */ | ||
46 | beq .clearbats_601 | ||
47 | |||
48 | /* Clear BATs */ | ||
49 | li r8,0 | ||
50 | mtspr SPRN_DBAT0U,r8 | ||
51 | mtspr SPRN_DBAT0L,r8 | ||
52 | mtspr SPRN_DBAT1U,r8 | ||
53 | mtspr SPRN_DBAT1L,r8 | ||
54 | mtspr SPRN_DBAT2U,r8 | ||
55 | mtspr SPRN_DBAT2L,r8 | ||
56 | mtspr SPRN_DBAT3U,r8 | ||
57 | mtspr SPRN_DBAT3L,r8 | ||
58 | .clearbats_601: | ||
59 | mtspr SPRN_IBAT0U,r8 | ||
60 | mtspr SPRN_IBAT0L,r8 | ||
61 | mtspr SPRN_IBAT1U,r8 | ||
62 | mtspr SPRN_IBAT1L,r8 | ||
63 | mtspr SPRN_IBAT2U,r8 | ||
64 | mtspr SPRN_IBAT2L,r8 | ||
65 | mtspr SPRN_IBAT3U,r8 | ||
66 | mtspr SPRN_IBAT3L,r8 | ||
67 | isync | ||
68 | sync | ||
69 | sync | ||
70 | |||
71 | /* Set segment registers */ | ||
72 | li r8,16 /* load up segment register values */ | ||
73 | mtctr r8 /* for context 0 */ | ||
74 | lis r8,0x2000 /* Ku = 1, VSID = 0 */ | ||
75 | li r10,0 | ||
76 | 3: mtsrin r8,r10 | ||
77 | addi r8,r8,0x111 /* increment VSID */ | ||
78 | addis r10,r10,0x1000 /* address of next segment */ | ||
79 | bdnz 3b | ||
80 | blr | ||
81 | |||
82 | .globl disable_6xx_l1cache | ||
83 | disable_6xx_l1cache: | ||
84 | /* Enable, invalidate and then disable the L1 icache/dcache. */ | ||
85 | li r8,0 | ||
86 | ori r8,r8,(HID0_ICE|HID0_DCE|HID0_ICFI|HID0_DCI) | ||
87 | mfspr r11,SPRN_HID0 | ||
88 | or r11,r11,r8 | ||
89 | andc r10,r11,r8 | ||
90 | isync | ||
91 | mtspr SPRN_HID0,r8 | ||
92 | sync | ||
93 | isync | ||
94 | mtspr SPRN_HID0,r10 | ||
95 | sync | ||
96 | isync | ||
97 | blr | ||
98 | #endif | ||
99 | |||
100 | .globl _setup_L2CR | ||
101 | _setup_L2CR: | ||
102 | /* | ||
103 | * We should be skipping this section on CPUs where this results in an | ||
104 | * illegal instruction. If not, please send trini@kernel.crashing.org | ||
105 | * the PVR of your CPU. | ||
106 | */ | ||
107 | /* Invalidate/disable L2 cache */ | ||
108 | sync | ||
109 | isync | ||
110 | mfspr r8,SPRN_L2CR | ||
111 | rlwinm r8,r8,0,1,31 | ||
112 | oris r8,r8,L2CR_L2I@h | ||
113 | sync | ||
114 | isync | ||
115 | mtspr SPRN_L2CR,r8 | ||
116 | sync | ||
117 | isync | ||
118 | |||
119 | /* Wait for the invalidation to complete */ | ||
120 | mfspr r8,SPRN_PVR | ||
121 | srwi r8,r8,16 | ||
122 | cmplwi cr0,r8,0x8000 /* 7450 */ | ||
123 | cmplwi cr1,r8,0x8001 /* 7455 */ | ||
124 | cmplwi cr2,r8,0x8002 /* 7457 */ | ||
125 | cror 4*cr0+eq,4*cr0+eq,4*cr1+eq /* Now test if any are true. */ | ||
126 | cror 4*cr0+eq,4*cr0+eq,4*cr2+eq | ||
127 | bne 2f | ||
128 | |||
129 | 1: mfspr r8,SPRN_L2CR /* On 745x, poll L2I bit (bit 10) */ | ||
130 | rlwinm. r9,r8,0,10,10 | ||
131 | bne 1b | ||
132 | b 3f | ||
133 | |||
134 | 2: mfspr r8,SPRN_L2CR /* On 75x & 74[01]0, poll L2IP bit (bit 31) */ | ||
135 | rlwinm. r9,r8,0,31,31 | ||
136 | bne 2b | ||
137 | |||
138 | 3: rlwinm r8,r8,0,11,9 /* Turn off L2I bit */ | ||
139 | sync | ||
140 | isync | ||
141 | mtspr SPRN_L2CR,r8 | ||
142 | sync | ||
143 | isync | ||
144 | blr | ||
145 | |||
146 | .globl _setup_L3CR | ||
147 | _setup_L3CR: | ||
148 | /* Invalidate/disable L3 cache */ | ||
149 | sync | ||
150 | isync | ||
151 | mfspr r8,SPRN_L3CR | ||
152 | rlwinm r8,r8,0,1,31 | ||
153 | ori r8,r8,L3CR_L3I@l | ||
154 | sync | ||
155 | isync | ||
156 | mtspr SPRN_L3CR,r8 | ||
157 | sync | ||
158 | isync | ||
159 | |||
160 | /* Wait for the invalidation to complete */ | ||
161 | 1: mfspr r8,SPRN_L3CR | ||
162 | rlwinm. r9,r8,0,21,21 | ||
163 | bne 1b | ||
164 | |||
165 | rlwinm r8,r8,0,22,20 /* Turn off L3I bit */ | ||
166 | sync | ||
167 | isync | ||
168 | mtspr SPRN_L3CR,r8 | ||
169 | sync | ||
170 | isync | ||
171 | blr | ||
172 | |||
173 | |||
174 | /* udelay (on non-601 processors) needs to know the period of the | ||
175 | * timebase in nanoseconds. This used to be hardcoded to be 60ns | ||
176 | * (period of 66MHz/4). Now a variable is used that is initialized to | ||
177 | * 60 for backward compatibility, but it can be overridden as necessary | ||
178 | * with code something like this: | ||
179 | * extern unsigned long timebase_period_ns; | ||
180 | * timebase_period_ns = 1000000000 / bd->bi_tbfreq; | ||
181 | */ | ||
182 | .data | ||
183 | .globl timebase_period_ns | ||
184 | timebase_period_ns: | ||
185 | .long 60 | ||
186 | |||
187 | .text | ||
188 | /* | ||
189 | * Delay for a number of microseconds | ||
190 | */ | ||
191 | .globl udelay | ||
192 | udelay: | ||
193 | mfspr r4,SPRN_PVR | ||
194 | srwi r4,r4,16 | ||
195 | cmpwi 0,r4,1 /* 601 ? */ | ||
196 | bne .udelay_not_601 | ||
197 | 00: li r0,86 /* Instructions / microsecond? */ | ||
198 | mtctr r0 | ||
199 | 10: addi r0,r0,0 /* NOP */ | ||
200 | bdnz 10b | ||
201 | subic. r3,r3,1 | ||
202 | bne 00b | ||
203 | blr | ||
204 | |||
205 | .udelay_not_601: | ||
206 | mulli r4,r3,1000 /* nanoseconds */ | ||
207 | /* Change r4 to be the number of ticks using: | ||
208 | * (nanoseconds + (timebase_period_ns - 1 )) / timebase_period_ns | ||
209 | * timebase_period_ns defaults to 60 (16.6MHz) */ | ||
210 | lis r5,timebase_period_ns@ha | ||
211 | lwz r5,timebase_period_ns@l(r5) | ||
212 | add r4,r4,r5 | ||
213 | addi r4,r4,-1 | ||
214 | divw r4,r4,r5 /* BUS ticks */ | ||
215 | 1: mftbu r5 | ||
216 | mftb r6 | ||
217 | mftbu r7 | ||
218 | cmpw 0,r5,r7 | ||
219 | bne 1b /* Get [synced] base time */ | ||
220 | addc r9,r6,r4 /* Compute end time */ | ||
221 | addze r8,r5 | ||
222 | 2: mftbu r5 | ||
223 | cmpw 0,r5,r8 | ||
224 | blt 2b | ||
225 | bgt 3f | ||
226 | mftb r6 | ||
227 | cmpw 0,r6,r9 | ||
228 | blt 2b | ||
229 | 3: blr | ||
230 | |||
231 | .section ".relocate_code","xa" | ||
232 | /* | ||
233 | * Flush and enable instruction cache | ||
234 | * First, flush the data cache in case it was enabled and may be | ||
235 | * holding instructions for copy back. | ||
236 | */ | ||
237 | _GLOBAL(flush_instruction_cache) | ||
238 | mflr r6 | ||
239 | bl flush_data_cache | ||
240 | |||
241 | #ifdef CONFIG_8xx | ||
242 | lis r3, IDC_INVALL@h | ||
243 | mtspr SPRN_IC_CST, r3 | ||
244 | lis r3, IDC_ENABLE@h | ||
245 | mtspr SPRN_IC_CST, r3 | ||
246 | lis r3, IDC_DISABLE@h | ||
247 | mtspr SPRN_DC_CST, r3 | ||
248 | #elif CONFIG_4xx | ||
249 | lis r3,start@h # r9 = &_start | ||
250 | lis r4,_etext@ha | ||
251 | addi r4,r4,_etext@l # r8 = &_etext | ||
252 | 1: dcbf r0,r3 # Flush the data cache | ||
253 | icbi r0,r3 # Invalidate the instruction cache | ||
254 | addi r3,r3,0x10 # Increment by one cache line | ||
255 | cmplwi cr0,r3,r4 # Are we at the end yet? | ||
256 | blt 1b # No, keep flushing and invalidating | ||
257 | #else | ||
258 | /* Enable, invalidate and then disable the L1 icache/dcache. */ | ||
259 | li r3,0 | ||
260 | ori r3,r3,(HID0_ICE|HID0_DCE|HID0_ICFI|HID0_DCI) | ||
261 | mfspr r4,SPRN_HID0 | ||
262 | or r5,r4,r3 | ||
263 | isync | ||
264 | mtspr SPRN_HID0,r5 | ||
265 | sync | ||
266 | isync | ||
267 | ori r5,r4,HID0_ICE /* Enable cache */ | ||
268 | mtspr SPRN_HID0,r5 | ||
269 | sync | ||
270 | isync | ||
271 | #endif | ||
272 | mtlr r6 | ||
273 | blr | ||
274 | |||
275 | #define NUM_CACHE_LINES 128*8 | ||
276 | #define cache_flush_buffer 0x1000 | ||
277 | |||
278 | /* | ||
279 | * Flush data cache | ||
280 | * Do this by just reading lots of stuff into the cache. | ||
281 | */ | ||
282 | _GLOBAL(flush_data_cache) | ||
283 | lis r3,cache_flush_buffer@h | ||
284 | ori r3,r3,cache_flush_buffer@l | ||
285 | li r4,NUM_CACHE_LINES | ||
286 | mtctr r4 | ||
287 | 00: lwz r4,0(r3) | ||
288 | addi r3,r3,L1_CACHE_BYTES /* Next line, please */ | ||
289 | bdnz 00b | ||
290 | 10: blr | ||
291 | |||
292 | .previous | ||
293 | |||
diff --git a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile new file mode 100644 index 000000000000..774de8e23871 --- /dev/null +++ b/arch/ppc/boot/images/Makefile | |||
@@ -0,0 +1,27 @@ | |||
1 | # | ||
2 | # This dir holds all of the images for PPC machines. | ||
3 | # Tom Rini January 2001 | ||
4 | |||
5 | MKIMAGE := $(srctree)/scripts/mkuboot.sh | ||
6 | |||
7 | extra-y := vmlinux.bin vmlinux.gz | ||
8 | |||
9 | OBJCOPYFLAGS_vmlinux.bin := -O binary | ||
10 | $(obj)/vmlinux.bin: vmlinux FORCE | ||
11 | $(call if_changed,objcopy) | ||
12 | |||
13 | $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE | ||
14 | $(call if_changed,gzip) | ||
15 | |||
16 | quiet_cmd_uimage = UIMAGE $@ | ||
17 | cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A ppc -O linux -T kernel \ | ||
18 | -C gzip -a 00000000 -e 00000000 -n 'Linux-$(KERNELRELEASE)' \ | ||
19 | -d $< $@ | ||
20 | |||
21 | targets += uImage | ||
22 | $(obj)/uImage: $(obj)/vmlinux.gz | ||
23 | $(call if_changed,uimage) | ||
24 | @echo ' Image $@ is ready' | ||
25 | |||
26 | # Files generated that shall be removed upon make clean | ||
27 | clean-files := sImage vmapus vmlinux* miboot* zImage* uImage | ||
diff --git a/arch/ppc/boot/include/cpc700.h b/arch/ppc/boot/include/cpc700.h new file mode 100644 index 000000000000..28cfcde44909 --- /dev/null +++ b/arch/ppc/boot/include/cpc700.h | |||
@@ -0,0 +1,26 @@ | |||
1 | |||
2 | #ifndef __PPC_BOOT_CPC700_H | ||
3 | #define __PPC_BOOT_CPC700_H | ||
4 | |||
5 | #define CPC700_MEM_CFGADDR 0xff500008 | ||
6 | #define CPC700_MEM_CFGDATA 0xff50000c | ||
7 | |||
8 | #define CPC700_MB0SA 0x38 | ||
9 | #define CPC700_MB0EA 0x58 | ||
10 | #define CPC700_MB1SA 0x3c | ||
11 | #define CPC700_MB1EA 0x5c | ||
12 | #define CPC700_MB2SA 0x40 | ||
13 | #define CPC700_MB2EA 0x60 | ||
14 | #define CPC700_MB3SA 0x44 | ||
15 | #define CPC700_MB3EA 0x64 | ||
16 | #define CPC700_MB4SA 0x48 | ||
17 | #define CPC700_MB4EA 0x68 | ||
18 | |||
19 | static inline long | ||
20 | cpc700_read_memreg(int reg) | ||
21 | { | ||
22 | out_be32((volatile unsigned int *) CPC700_MEM_CFGADDR, reg); | ||
23 | return in_be32((volatile unsigned int *) CPC700_MEM_CFGDATA); | ||
24 | } | ||
25 | |||
26 | #endif | ||
diff --git a/arch/ppc/boot/include/iso_font.h b/arch/ppc/boot/include/iso_font.h new file mode 100644 index 000000000000..bff050e002b7 --- /dev/null +++ b/arch/ppc/boot/include/iso_font.h | |||
@@ -0,0 +1,257 @@ | |||
1 | static const unsigned char font[] = { | ||
2 | /* 0x00 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
3 | /* 0x01 */ 0x00,0x00,0x7E,0x81,0xA5,0x81,0x81,0xBD,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00, | ||
4 | /* 0x02 */ 0x00,0x00,0x7E,0xFF,0xDB,0xFF,0xFF,0xC3,0xC3,0xE7,0xFF,0x7E,0x00,0x00,0x00,0x00, | ||
5 | /* 0x03 */ 0x00,0x00,0x00,0x00,0x6C,0xFE,0xFE,0xFE,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00, | ||
6 | /* 0x04 */ 0x00,0x00,0x00,0x00,0x10,0x38,0x7C,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,0x00, | ||
7 | /* 0x05 */ 0x00,0x00,0x00,0x18,0x3C,0x3C,0xE7,0xE7,0xE7,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, | ||
8 | /* 0x06 */ 0x00,0x00,0x00,0x18,0x3C,0x7E,0xFF,0xFF,0x7E,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, | ||
9 | /* 0x07 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00, | ||
10 | /* 0x08 */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xC3,0xC3,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
11 | /* 0x09 */ 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x42,0x42,0x66,0x3C,0x00,0x00,0x00,0x00,0x00, | ||
12 | /* 0x0A */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0x99,0xBD,0xBD,0x99,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
13 | /* 0x0B */ 0x00,0x00,0x3E,0x0E,0x1A,0x32,0x78,0xCC,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00, | ||
14 | /* 0x0C */ 0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00, | ||
15 | /* 0x0D */ 0x00,0x00,0x30,0x38,0x3C,0x36,0x33,0x30,0x30,0x70,0xF0,0xE0,0x00,0x00,0x00,0x00, | ||
16 | /* 0x0E */ 0x00,0x00,0x7F,0x63,0x7F,0x63,0x63,0x63,0x63,0x67,0xE7,0xE6,0xC0,0x00,0x00,0x00, | ||
17 | /* 0x0F */ 0x00,0x00,0x00,0x18,0x18,0xDB,0x3C,0xE7,0x3C,0xDB,0x18,0x18,0x00,0x00,0x00,0x00, | ||
18 | /* 0x10 */ 0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFE,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00, | ||
19 | /* 0x11 */ 0x00,0x02,0x06,0x0E,0x1E,0x3E,0xFE,0x3E,0x1E,0x0E,0x06,0x02,0x00,0x00,0x00,0x00, | ||
20 | /* 0x12 */ 0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,0x00, | ||
21 | /* 0x13 */ 0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00, | ||
22 | /* 0x14 */ 0x00,0x00,0x7F,0xDB,0xDB,0xDB,0x7B,0x1B,0x1B,0x1B,0x1B,0x1B,0x00,0x00,0x00,0x00, | ||
23 | /* 0x15 */ 0x00,0x7C,0xC6,0x60,0x38,0x6C,0xC6,0xC6,0x6C,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00, | ||
24 | /* 0x16 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00, | ||
25 | /* 0x17 */ 0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00, | ||
26 | /* 0x18 */ 0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, | ||
27 | /* 0x19 */ 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00, | ||
28 | /* 0x1A */ 0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0xFE,0x0C,0x18,0x00,0x00,0x00,0x00,0x00,0x00, | ||
29 | /* 0x1B */ 0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xFE,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00, | ||
30 | /* 0x1C */ 0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, | ||
31 | /* 0x1D */ 0x00,0x00,0x00,0x00,0x00,0x28,0x6C,0xFE,0x6C,0x28,0x00,0x00,0x00,0x00,0x00,0x00, | ||
32 | /* 0x1E */ 0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7C,0x7C,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00, | ||
33 | /* 0x1F */ 0x00,0x00,0x00,0x00,0xFE,0xFE,0x7C,0x7C,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00, | ||
34 | /* 0x20 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
35 | /* 0x21 */ 0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, | ||
36 | /* 0x22 */ 0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
37 | /* 0x23 */ 0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00, | ||
38 | /* 0x24 */ 0x18,0x18,0x7C,0xC6,0xC2,0xC0,0x7C,0x06,0x06,0x86,0xC6,0x7C,0x18,0x18,0x00,0x00, | ||
39 | /* 0x25 */ 0x00,0x00,0x00,0x00,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC6,0x86,0x00,0x00,0x00,0x00, | ||
40 | /* 0x26 */ 0x00,0x00,0x38,0x6C,0x6C,0x38,0x76,0xDC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, | ||
41 | /* 0x27 */ 0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
42 | /* 0x28 */ 0x00,0x00,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x00,0x00,0x00,0x00, | ||
43 | /* 0x29 */ 0x00,0x00,0x30,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x30,0x00,0x00,0x00,0x00, | ||
44 | /* 0x2A */ 0x00,0x00,0x00,0x00,0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00, | ||
45 | /* 0x2B */ 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, | ||
46 | /* 0x2C */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00, | ||
47 | /* 0x2D */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
48 | /* 0x2E */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, | ||
49 | /* 0x2F */ 0x00,0x00,0x00,0x00,0x02,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00, | ||
50 | /* 0x30 */ 0x00,0x00,0x38,0x6C,0xC6,0xC6,0xD6,0xD6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00, | ||
51 | /* 0x31 */ 0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00, | ||
52 | /* 0x32 */ 0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00, | ||
53 | /* 0x33 */ 0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
54 | /* 0x34 */ 0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00, | ||
55 | /* 0x35 */ 0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
56 | /* 0x36 */ 0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
57 | /* 0x37 */ 0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00, | ||
58 | /* 0x38 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
59 | /* 0x39 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00, | ||
60 | /* 0x3A */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, | ||
61 | /* 0x3B */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00, | ||
62 | /* 0x3C */ 0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00, | ||
63 | /* 0x3D */ 0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
64 | /* 0x3E */ 0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00, | ||
65 | /* 0x3F */ 0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, | ||
66 | /* 0x40 */ 0x00,0x00,0x00,0x7C,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0x7C,0x00,0x00,0x00,0x00, | ||
67 | /* 0x41 */ 0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, | ||
68 | /* 0x42 */ 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00, | ||
69 | /* 0x43 */ 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00, | ||
70 | /* 0x44 */ 0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00, | ||
71 | /* 0x45 */ 0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00, | ||
72 | /* 0x46 */ 0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00, | ||
73 | /* 0x47 */ 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xDE,0xC6,0xC6,0x66,0x3A,0x00,0x00,0x00,0x00, | ||
74 | /* 0x48 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, | ||
75 | /* 0x49 */ 0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, | ||
76 | /* 0x4A */ 0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00, | ||
77 | /* 0x4B */ 0x00,0x00,0xE6,0x66,0x66,0x6C,0x78,0x78,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00, | ||
78 | /* 0x4C */ 0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00, | ||
79 | /* 0x4D */ 0x00,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, | ||
80 | /* 0x4E */ 0x00,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, | ||
81 | /* 0x4F */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
82 | /* 0x50 */ 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00, | ||
83 | /* 0x51 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xDE,0x7C,0x0C,0x0E,0x00,0x00, | ||
84 | /* 0x52 */ 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x6C,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00, | ||
85 | /* 0x53 */ 0x00,0x00,0x7C,0xC6,0xC6,0x60,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
86 | /* 0x54 */ 0x00,0x00,0x7E,0x7E,0x5A,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, | ||
87 | /* 0x55 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
88 | /* 0x56 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00, | ||
89 | /* 0x57 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0xEE,0x6C,0x00,0x00,0x00,0x00, | ||
90 | /* 0x58 */ 0x00,0x00,0xC6,0xC6,0x6C,0x7C,0x38,0x38,0x7C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00, | ||
91 | /* 0x59 */ 0x00,0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, | ||
92 | /* 0x5A */ 0x00,0x00,0xFE,0xC6,0x86,0x0C,0x18,0x30,0x60,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00, | ||
93 | /* 0x5B */ 0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00, | ||
94 | /* 0x5C */ 0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x06,0x02,0x00,0x00,0x00,0x00, | ||
95 | /* 0x5D */ 0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00, | ||
96 | /* 0x5E */ 0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
97 | /* 0x5F */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00, | ||
98 | /* 0x60 */ 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
99 | /* 0x61 */ 0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, | ||
100 | /* 0x62 */ 0x00,0x00,0xE0,0x60,0x60,0x78,0x6C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x00,0x00, | ||
101 | /* 0x63 */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
102 | /* 0x64 */ 0x00,0x00,0x1C,0x0C,0x0C,0x3C,0x6C,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, | ||
103 | /* 0x65 */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
104 | /* 0x66 */ 0x00,0x00,0x38,0x6C,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00, | ||
105 | /* 0x67 */ 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x66,0x3E,0x06,0x66,0x3C,0x00, | ||
106 | /* 0x68 */ 0x00,0x00,0xE0,0x60,0x60,0x6C,0x76,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00, | ||
107 | /* 0x69 */ 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, | ||
108 | /* 0x6A */ 0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00, | ||
109 | /* 0x6B */ 0x00,0x00,0xE0,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0xE6,0x00,0x00,0x00,0x00, | ||
110 | /* 0x6C */ 0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, | ||
111 | /* 0x6D */ 0x00,0x00,0x00,0x00,0x00,0x6C,0xFE,0xD6,0xD6,0xD6,0xC6,0xC6,0x00,0x00,0x00,0x00, | ||
112 | /* 0x6E */ 0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, | ||
113 | /* 0x6F */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
114 | /* 0x70 */ 0x00,0x00,0x00,0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00, | ||
115 | /* 0x71 */ 0x00,0x00,0x00,0x00,0x00,0x7E,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0x1E,0x00, | ||
116 | /* 0x72 */ 0x00,0x00,0x00,0x00,0x00,0xDC,0x76,0x66,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00, | ||
117 | /* 0x73 */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0x60,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
118 | /* 0x74 */ 0x00,0x00,0x10,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00, | ||
119 | /* 0x75 */ 0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, | ||
120 | /* 0x76 */ 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x00, | ||
121 | /* 0x77 */ 0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0x6C,0x00,0x00,0x00,0x00, | ||
122 | /* 0x78 */ 0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00, | ||
123 | /* 0x79 */ 0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00, | ||
124 | /* 0x7A */ 0x00,0x00,0x00,0x00,0x00,0xFE,0xCC,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00, | ||
125 | /* 0x7B */ 0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00, | ||
126 | /* 0x7C */ 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, | ||
127 | /* 0x7D */ 0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00, | ||
128 | /* 0x7E */ 0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
129 | /* 0x7F */ 0x00,0x00,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0x00,0x00,0x00,0x00,0x00, | ||
130 | /* 0x80 */ 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x0C,0x06,0x7C,0x00,0x00, | ||
131 | /* 0x81 */ 0x00,0x00,0xCC,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, | ||
132 | /* 0x82 */ 0x00,0x0C,0x18,0x30,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
133 | /* 0x83 */ 0x00,0x10,0x38,0x6C,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, | ||
134 | /* 0x84 */ 0x00,0x00,0xCC,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, | ||
135 | /* 0x85 */ 0x00,0x60,0x30,0x18,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, | ||
136 | /* 0x86 */ 0x00,0x38,0x6C,0x38,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, | ||
137 | /* 0x87 */ 0x00,0x00,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x0C,0x06,0x3C,0x00,0x00,0x00, | ||
138 | /* 0x88 */ 0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
139 | /* 0x89 */ 0x00,0x00,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
140 | /* 0x8A */ 0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
141 | /* 0x8B */ 0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, | ||
142 | /* 0x8C */ 0x00,0x18,0x3C,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, | ||
143 | /* 0x8D */ 0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, | ||
144 | /* 0x8E */ 0x00,0xC6,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, | ||
145 | /* 0x8F */ 0x38,0x6C,0x38,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, | ||
146 | /* 0x90 */ 0x18,0x30,0x60,0x00,0xFE,0x66,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00, | ||
147 | /* 0x91 */ 0x00,0x00,0x00,0x00,0x00,0xCC,0x76,0x36,0x7E,0xD8,0xD8,0x6E,0x00,0x00,0x00,0x00, | ||
148 | /* 0x92 */ 0x00,0x00,0x3E,0x6C,0xCC,0xCC,0xFE,0xCC,0xCC,0xCC,0xCC,0xCE,0x00,0x00,0x00,0x00, | ||
149 | /* 0x93 */ 0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
150 | /* 0x94 */ 0x00,0x00,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
151 | /* 0x95 */ 0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
152 | /* 0x96 */ 0x00,0x30,0x78,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, | ||
153 | /* 0x97 */ 0x00,0x60,0x30,0x18,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, | ||
154 | /* 0x98 */ 0x00,0x00,0xC6,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00, | ||
155 | /* 0x99 */ 0x00,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
156 | /* 0x9A */ 0x00,0xC6,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
157 | /* 0x9B */ 0x00,0x18,0x18,0x3C,0x66,0x60,0x60,0x60,0x66,0x3C,0x18,0x18,0x00,0x00,0x00,0x00, | ||
158 | /* 0x9C */ 0x00,0x38,0x6C,0x64,0x60,0xF8,0x60,0x60,0x60,0x60,0xE6,0xFC,0x00,0x00,0x00,0x00, | ||
159 | /* 0x9D */ 0x00,0x00,0x66,0x66,0x3C,0x18,0x7E,0x18,0x7E,0x18,0x18,0x18,0x00,0x00,0x00,0x00, | ||
160 | /* 0x9E */ 0x00,0xF8,0xCC,0xCC,0xF8,0xC4,0xCC,0xDE,0xCC,0xCC,0xCC,0xC6,0x00,0x00,0x00,0x00, | ||
161 | /* 0x9F */ 0x00,0x0E,0x1B,0x18,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x18,0xD8,0x70,0x00,0x00, | ||
162 | /* 0xA0 */ 0x00,0x18,0x30,0x60,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, | ||
163 | /* 0xA1 */ 0x00,0x0C,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, | ||
164 | /* 0xA2 */ 0x00,0x18,0x30,0x60,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
165 | /* 0xA3 */ 0x00,0x18,0x30,0x60,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, | ||
166 | /* 0xA4 */ 0x00,0x00,0x76,0xDC,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, | ||
167 | /* 0xA5 */ 0x76,0xDC,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, | ||
168 | /* 0xA6 */ 0x00,0x3C,0x6C,0x6C,0x3E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
169 | /* 0xA7 */ 0x00,0x38,0x6C,0x6C,0x38,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
170 | /* 0xA8 */ 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xC0,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, | ||
171 | /* 0xA9 */ 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00, | ||
172 | /* 0xAA */ 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00, | ||
173 | /* 0xAB */ 0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x60,0xDC,0x86,0x0C,0x18,0x3E,0x00,0x00, | ||
174 | /* 0xAC */ 0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x66,0xCE,0x9E,0x3E,0x06,0x06,0x00,0x00, | ||
175 | /* 0xAD */ 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3C,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00, | ||
176 | /* 0xAE */ 0x00,0x00,0x00,0x00,0x00,0x36,0x6C,0xD8,0x6C,0x36,0x00,0x00,0x00,0x00,0x00,0x00, | ||
177 | /* 0xAF */ 0x00,0x00,0x00,0x00,0x00,0xD8,0x6C,0x36,0x6C,0xD8,0x00,0x00,0x00,0x00,0x00,0x00, | ||
178 | /* 0xB0 */ 0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44, | ||
179 | /* 0xB1 */ 0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA, | ||
180 | /* 0xB2 */ 0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77, | ||
181 | /* 0xB3 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, | ||
182 | /* 0xB4 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, | ||
183 | /* 0xB5 */ 0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, | ||
184 | /* 0xB6 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, | ||
185 | /* 0xB7 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, | ||
186 | /* 0xB8 */ 0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, | ||
187 | /* 0xB9 */ 0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, | ||
188 | /* 0xBA */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, | ||
189 | /* 0xBB */ 0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, | ||
190 | /* 0xBC */ 0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
191 | /* 0xBD */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
192 | /* 0xBE */ 0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
193 | /* 0xBF */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, | ||
194 | /* 0xC0 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
195 | /* 0xC1 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
196 | /* 0xC2 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, | ||
197 | /* 0xC3 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, | ||
198 | /* 0xC4 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
199 | /* 0xC5 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, | ||
200 | /* 0xC6 */ 0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, | ||
201 | /* 0xC7 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, | ||
202 | /* 0xC8 */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
203 | /* 0xC9 */ 0x00,0x00,0x00,0x00,0x00,0x3F,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, | ||
204 | /* 0xCA */ 0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
205 | /* 0xCB */ 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, | ||
206 | /* 0xCC */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, | ||
207 | /* 0xCD */ 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
208 | /* 0xCE */ 0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, | ||
209 | /* 0xCF */ 0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
210 | /* 0xD0 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
211 | /* 0xD1 */ 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, | ||
212 | /* 0xD2 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, | ||
213 | /* 0xD3 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
214 | /* 0xD4 */ 0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
215 | /* 0xD5 */ 0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, | ||
216 | /* 0xD6 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, | ||
217 | /* 0xD7 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, | ||
218 | /* 0xD8 */ 0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, | ||
219 | /* 0xD9 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
220 | /* 0xDA */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, | ||
221 | /* 0xDB */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
222 | /* 0xDC */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
223 | /* 0xDD */ 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0, | ||
224 | /* 0xDE */ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, | ||
225 | /* 0xDF */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
226 | /* 0xE0 */ 0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0xD8,0xD8,0xD8,0xDC,0x76,0x00,0x00,0x00,0x00, | ||
227 | /* 0xE1 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xFC,0xC6,0xC6,0xC6,0xC6,0xDC,0xC0,0xC0,0x00,0x00, | ||
228 | /* 0xE2 */ 0x00,0x00,0xFE,0xC6,0xC6,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00, | ||
229 | /* 0xE3 */ 0x00,0x00,0x00,0x00,0x00,0xFE,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00, | ||
230 | /* 0xE4 */ 0x00,0x00,0xFE,0xC6,0x60,0x30,0x18,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00, | ||
231 | /* 0xE5 */ 0x00,0x00,0x00,0x00,0x00,0x7E,0xD8,0xD8,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00, | ||
232 | /* 0xE6 */ 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0xC0,0x00,0x00,0x00, | ||
233 | /* 0xE7 */ 0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, | ||
234 | /* 0xE8 */ 0x00,0x00,0x7E,0x18,0x3C,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00, | ||
235 | /* 0xE9 */ 0x00,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00, | ||
236 | /* 0xEA */ 0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0x6C,0x6C,0x6C,0x6C,0xEE,0x00,0x00,0x00,0x00, | ||
237 | /* 0xEB */ 0x00,0x00,0x1E,0x30,0x18,0x0C,0x3E,0x66,0x66,0x66,0x66,0x3C,0x00,0x00,0x00,0x00, | ||
238 | /* 0xEC */ 0x00,0x00,0x00,0x00,0x00,0x7E,0xDB,0xDB,0xDB,0x7E,0x00,0x00,0x00,0x00,0x00,0x00, | ||
239 | /* 0xED */ 0x00,0x00,0x00,0x03,0x06,0x7E,0xDB,0xDB,0xF3,0x7E,0x60,0xC0,0x00,0x00,0x00,0x00, | ||
240 | /* 0xEE */ 0x00,0x00,0x1C,0x30,0x60,0x60,0x7C,0x60,0x60,0x60,0x30,0x1C,0x00,0x00,0x00,0x00, | ||
241 | /* 0xEF */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, | ||
242 | /* 0xF0 */ 0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00, | ||
243 | /* 0xF1 */ 0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0xFF,0x00,0x00,0x00,0x00, | ||
244 | /* 0xF2 */ 0x00,0x00,0x00,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00,0x7E,0x00,0x00,0x00,0x00, | ||
245 | /* 0xF3 */ 0x00,0x00,0x00,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00,0x7E,0x00,0x00,0x00,0x00, | ||
246 | /* 0xF4 */ 0x00,0x0E,0x1B,0x1B,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, | ||
247 | /* 0xF5 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00, | ||
248 | /* 0xF6 */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7E,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, | ||
249 | /* 0xF7 */ 0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00, | ||
250 | /* 0xF8 */ 0x00,0x38,0x6C,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
251 | /* 0xF9 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
252 | /* 0xFA */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
253 | /* 0xFB */ 0x00,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0xEC,0x6C,0x6C,0x3C,0x1C,0x00,0x00,0x00,0x00, | ||
254 | /* 0xFC */ 0x00,0xD8,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
255 | /* 0xFD */ 0x00,0x70,0xD8,0x30,0x60,0xC8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
256 | /* 0xFE */ 0x00,0x00,0x00,0x00,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x00,0x00,0x00,0x00,0x00, | ||
257 | }; | ||
diff --git a/arch/ppc/boot/include/mpc10x.h b/arch/ppc/boot/include/mpc10x.h new file mode 100644 index 000000000000..6cd40ecabc74 --- /dev/null +++ b/arch/ppc/boot/include/mpc10x.h | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/include/mpc10.h | ||
3 | * | ||
4 | * Common defines for the Motorola SPS MPC106/8240/107 Host bridge/Mem | ||
5 | * ctrl/EPIC/etc. | ||
6 | * | ||
7 | * Author: Tom Rini <trini@mvista.com> | ||
8 | * | ||
9 | * This is a heavily stripped down version of: | ||
10 | * include/asm-ppc/mpc10x.h | ||
11 | * | ||
12 | * Author: Mark A. Greer | ||
13 | * mgreer@mvista.com | ||
14 | * | ||
15 | * 2001-2002 (c) MontaVista, Software, Inc. This file is licensed under | ||
16 | * the terms of the GNU General Public License version 2. This program | ||
17 | * is licensed "as is" without any warranty of any kind, whether express | ||
18 | * or implied. | ||
19 | */ | ||
20 | #ifndef __BOOT_MPC10X_H__ | ||
21 | #define __BOOT_MPC10X_H__ | ||
22 | |||
23 | /* | ||
24 | * The values here don't completely map everything but should work in most | ||
25 | * cases. | ||
26 | * | ||
27 | * MAP A (PReP Map) | ||
28 | * Processor: 0x80000000 - 0x807fffff -> PCI I/O: 0x00000000 - 0x007fffff | ||
29 | * Processor: 0xc0000000 - 0xdfffffff -> PCI MEM: 0x00000000 - 0x1fffffff | ||
30 | * PCI MEM: 0x80000000 -> Processor System Memory: 0x00000000 | ||
31 | * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB) | ||
32 | * | ||
33 | * MAP B (CHRP Map) | ||
34 | * Processor: 0xfe000000 - 0xfebfffff -> PCI I/O: 0x00000000 - 0x00bfffff | ||
35 | * Processor: 0x80000000 - 0xbfffffff -> PCI MEM: 0x80000000 - 0xbfffffff | ||
36 | * PCI MEM: 0x00000000 -> Processor System Memory: 0x00000000 | ||
37 | * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB) | ||
38 | */ | ||
39 | |||
40 | /* Define the type of map to use */ | ||
41 | #define MPC10X_MEM_MAP_A 1 | ||
42 | #define MPC10X_MEM_MAP_B 2 | ||
43 | |||
44 | /* Map A (PReP Map) Defines */ | ||
45 | #define MPC10X_MAPA_CNFG_ADDR 0x80000cf8 | ||
46 | #define MPC10X_MAPA_CNFG_DATA 0x80000cfc | ||
47 | |||
48 | /* Map B (CHRP Map) Defines */ | ||
49 | #define MPC10X_MAPB_CNFG_ADDR 0xfec00000 | ||
50 | #define MPC10X_MAPB_CNFG_DATA 0xfee00000 | ||
51 | |||
52 | /* Define offsets for the memory controller registers in the config space */ | ||
53 | #define MPC10X_MCTLR_MEM_START_1 0x80 /* Banks 0-3 */ | ||
54 | #define MPC10X_MCTLR_MEM_START_2 0x84 /* Banks 4-7 */ | ||
55 | #define MPC10X_MCTLR_EXT_MEM_START_1 0x88 /* Banks 0-3 */ | ||
56 | #define MPC10X_MCTLR_EXT_MEM_START_2 0x8c /* Banks 4-7 */ | ||
57 | |||
58 | #define MPC10X_MCTLR_MEM_END_1 0x90 /* Banks 0-3 */ | ||
59 | #define MPC10X_MCTLR_MEM_END_2 0x94 /* Banks 4-7 */ | ||
60 | #define MPC10X_MCTLR_EXT_MEM_END_1 0x98 /* Banks 0-3 */ | ||
61 | #define MPC10X_MCTLR_EXT_MEM_END_2 0x9c /* Banks 4-7 */ | ||
62 | |||
63 | #define MPC10X_MCTLR_MEM_BANK_ENABLES 0xa0 | ||
64 | |||
65 | #endif /* __BOOT_MPC10X_H__ */ | ||
diff --git a/arch/ppc/boot/include/mpsc_defs.h b/arch/ppc/boot/include/mpsc_defs.h new file mode 100644 index 000000000000..2ce7bbba7277 --- /dev/null +++ b/arch/ppc/boot/include/mpsc_defs.h | |||
@@ -0,0 +1,146 @@ | |||
1 | /* | ||
2 | * drivers/serial/mpsc/mpsc_defs.h | ||
3 | * | ||
4 | * Register definitions for the Marvell Multi-Protocol Serial Controller (MPSC), | ||
5 | * Serial DMA Controller (SDMA), and Baud Rate Generator (BRG). | ||
6 | * | ||
7 | * Author: Mark A. Greer <mgreer@mvista.com> | ||
8 | * | ||
9 | * 2004 (c) MontaVista, Software, Inc. This file is licensed under | ||
10 | * the terms of the GNU General Public License version 2. This program | ||
11 | * is licensed "as is" without any warranty of any kind, whether express | ||
12 | * or implied. | ||
13 | */ | ||
14 | #ifndef _PPC_BOOT_MPSC_DEFS_H__ | ||
15 | #define _PPC_BOOT_MPSC_DEFS_H__ | ||
16 | |||
17 | #define MPSC_NUM_CTLRS 2 | ||
18 | |||
19 | /* | ||
20 | ***************************************************************************** | ||
21 | * | ||
22 | * Multi-Protocol Serial Controller Interface Registers | ||
23 | * | ||
24 | ***************************************************************************** | ||
25 | */ | ||
26 | |||
27 | /* Main Configuratino Register Offsets */ | ||
28 | #define MPSC_MMCRL 0x0000 | ||
29 | #define MPSC_MMCRH 0x0004 | ||
30 | #define MPSC_MPCR 0x0008 | ||
31 | #define MPSC_CHR_1 0x000c | ||
32 | #define MPSC_CHR_2 0x0010 | ||
33 | #define MPSC_CHR_3 0x0014 | ||
34 | #define MPSC_CHR_4 0x0018 | ||
35 | #define MPSC_CHR_5 0x001c | ||
36 | #define MPSC_CHR_6 0x0020 | ||
37 | #define MPSC_CHR_7 0x0024 | ||
38 | #define MPSC_CHR_8 0x0028 | ||
39 | #define MPSC_CHR_9 0x002c | ||
40 | #define MPSC_CHR_10 0x0030 | ||
41 | #define MPSC_CHR_11 0x0034 | ||
42 | |||
43 | #define MPSC_MPCR_CL_5 0 | ||
44 | #define MPSC_MPCR_CL_6 1 | ||
45 | #define MPSC_MPCR_CL_7 2 | ||
46 | #define MPSC_MPCR_CL_8 3 | ||
47 | #define MPSC_MPCR_SBL_1 0 | ||
48 | #define MPSC_MPCR_SBL_2 3 | ||
49 | |||
50 | #define MPSC_CHR_2_TEV (1<<1) | ||
51 | #define MPSC_CHR_2_TA (1<<7) | ||
52 | #define MPSC_CHR_2_TTCS (1<<9) | ||
53 | #define MPSC_CHR_2_REV (1<<17) | ||
54 | #define MPSC_CHR_2_RA (1<<23) | ||
55 | #define MPSC_CHR_2_CRD (1<<25) | ||
56 | #define MPSC_CHR_2_EH (1<<31) | ||
57 | #define MPSC_CHR_2_PAR_ODD 0 | ||
58 | #define MPSC_CHR_2_PAR_SPACE 1 | ||
59 | #define MPSC_CHR_2_PAR_EVEN 2 | ||
60 | #define MPSC_CHR_2_PAR_MARK 3 | ||
61 | |||
62 | /* MPSC Signal Routing */ | ||
63 | #define MPSC_MRR 0x0000 | ||
64 | #define MPSC_RCRR 0x0004 | ||
65 | #define MPSC_TCRR 0x0008 | ||
66 | |||
67 | /* | ||
68 | ***************************************************************************** | ||
69 | * | ||
70 | * Serial DMA Controller Interface Registers | ||
71 | * | ||
72 | ***************************************************************************** | ||
73 | */ | ||
74 | |||
75 | #define SDMA_SDC 0x0000 | ||
76 | #define SDMA_SDCM 0x0008 | ||
77 | #define SDMA_RX_DESC 0x0800 | ||
78 | #define SDMA_RX_BUF_PTR 0x0808 | ||
79 | #define SDMA_SCRDP 0x0810 | ||
80 | #define SDMA_TX_DESC 0x0c00 | ||
81 | #define SDMA_SCTDP 0x0c10 | ||
82 | #define SDMA_SFTDP 0x0c14 | ||
83 | |||
84 | #define SDMA_DESC_CMDSTAT_PE (1<<0) | ||
85 | #define SDMA_DESC_CMDSTAT_CDL (1<<1) | ||
86 | #define SDMA_DESC_CMDSTAT_FR (1<<3) | ||
87 | #define SDMA_DESC_CMDSTAT_OR (1<<6) | ||
88 | #define SDMA_DESC_CMDSTAT_BR (1<<9) | ||
89 | #define SDMA_DESC_CMDSTAT_MI (1<<10) | ||
90 | #define SDMA_DESC_CMDSTAT_A (1<<11) | ||
91 | #define SDMA_DESC_CMDSTAT_AM (1<<12) | ||
92 | #define SDMA_DESC_CMDSTAT_CT (1<<13) | ||
93 | #define SDMA_DESC_CMDSTAT_C (1<<14) | ||
94 | #define SDMA_DESC_CMDSTAT_ES (1<<15) | ||
95 | #define SDMA_DESC_CMDSTAT_L (1<<16) | ||
96 | #define SDMA_DESC_CMDSTAT_F (1<<17) | ||
97 | #define SDMA_DESC_CMDSTAT_P (1<<18) | ||
98 | #define SDMA_DESC_CMDSTAT_EI (1<<23) | ||
99 | #define SDMA_DESC_CMDSTAT_O (1<<31) | ||
100 | |||
101 | #define SDMA_DESC_DFLT (SDMA_DESC_CMDSTAT_O | \ | ||
102 | SDMA_DESC_CMDSTAT_EI) | ||
103 | |||
104 | #define SDMA_SDC_RFT (1<<0) | ||
105 | #define SDMA_SDC_SFM (1<<1) | ||
106 | #define SDMA_SDC_BLMR (1<<6) | ||
107 | #define SDMA_SDC_BLMT (1<<7) | ||
108 | #define SDMA_SDC_POVR (1<<8) | ||
109 | #define SDMA_SDC_RIFB (1<<9) | ||
110 | |||
111 | #define SDMA_SDCM_ERD (1<<7) | ||
112 | #define SDMA_SDCM_AR (1<<15) | ||
113 | #define SDMA_SDCM_STD (1<<16) | ||
114 | #define SDMA_SDCM_TXD (1<<23) | ||
115 | #define SDMA_SDCM_AT (1<<31) | ||
116 | |||
117 | #define SDMA_0_CAUSE_RXBUF (1<<0) | ||
118 | #define SDMA_0_CAUSE_RXERR (1<<1) | ||
119 | #define SDMA_0_CAUSE_TXBUF (1<<2) | ||
120 | #define SDMA_0_CAUSE_TXEND (1<<3) | ||
121 | #define SDMA_1_CAUSE_RXBUF (1<<8) | ||
122 | #define SDMA_1_CAUSE_RXERR (1<<9) | ||
123 | #define SDMA_1_CAUSE_TXBUF (1<<10) | ||
124 | #define SDMA_1_CAUSE_TXEND (1<<11) | ||
125 | |||
126 | #define SDMA_CAUSE_RX_MASK (SDMA_0_CAUSE_RXBUF | SDMA_0_CAUSE_RXERR | \ | ||
127 | SDMA_1_CAUSE_RXBUF | SDMA_1_CAUSE_RXERR) | ||
128 | #define SDMA_CAUSE_TX_MASK (SDMA_0_CAUSE_TXBUF | SDMA_0_CAUSE_TXEND | \ | ||
129 | SDMA_1_CAUSE_TXBUF | SDMA_1_CAUSE_TXEND) | ||
130 | |||
131 | /* SDMA Interrupt registers */ | ||
132 | #define SDMA_INTR_CAUSE 0x0000 | ||
133 | #define SDMA_INTR_MASK 0x0080 | ||
134 | |||
135 | /* | ||
136 | ***************************************************************************** | ||
137 | * | ||
138 | * Baud Rate Generator Interface Registers | ||
139 | * | ||
140 | ***************************************************************************** | ||
141 | */ | ||
142 | |||
143 | #define BRG_BCR 0x0000 | ||
144 | #define BRG_BTR 0x0004 | ||
145 | |||
146 | #endif /*_PPC_BOOT_MPSC_DEFS_H__ */ | ||
diff --git a/arch/ppc/boot/include/nonstdio.h b/arch/ppc/boot/include/nonstdio.h new file mode 100644 index 000000000000..f2b5526faef3 --- /dev/null +++ b/arch/ppc/boot/include/nonstdio.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This is sort of a catchall for I/O related functions. Stuff that | ||
10 | * wouldn't be in 'stdio.h' normally is here, and it's 'nonstdio.h' | ||
11 | * for a reason. -- Tom | ||
12 | */ | ||
13 | typedef int FILE; | ||
14 | extern FILE *stdin, *stdout; | ||
15 | #define NULL ((void *)0) | ||
16 | #define EOF (-1) | ||
17 | #define fopen(n, m) NULL | ||
18 | #define fflush(f) 0 | ||
19 | #define fclose(f) 0 | ||
20 | #define perror(s) printf("%s: no files!\n", (s)) | ||
21 | |||
22 | extern int getc(void); | ||
23 | extern int printf(const char *format, ...); | ||
24 | extern int sprintf(char *str, const char *format, ...); | ||
25 | extern int tstc(void); | ||
26 | extern void exit(void); | ||
27 | extern void outb(int port, unsigned char val); | ||
28 | extern void putc(const char c); | ||
29 | extern void puthex(unsigned long val); | ||
30 | extern void puts(const char *); | ||
31 | extern void udelay(long delay); | ||
32 | extern unsigned char inb(int port); | ||
33 | extern void board_isa_init(void); | ||
34 | extern void ISA_init(unsigned long base); | ||
diff --git a/arch/ppc/boot/include/of1275.h b/arch/ppc/boot/include/of1275.h new file mode 100644 index 000000000000..69173df76db0 --- /dev/null +++ b/arch/ppc/boot/include/of1275.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * Copyright (C) Leigh Brown 2002. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | typedef void *prom_handle; | ||
12 | typedef void *ihandle; | ||
13 | typedef void *phandle; | ||
14 | typedef int (*prom_entry)(void *); | ||
15 | |||
16 | #define OF_INVALID_HANDLE ((prom_handle)-1UL) | ||
17 | |||
18 | extern prom_entry of_prom_entry; | ||
19 | |||
20 | /* function declarations */ | ||
21 | |||
22 | void * claim(unsigned int virt, unsigned int size, unsigned int align); | ||
23 | int map(unsigned int phys, unsigned int virt, unsigned int size); | ||
24 | void enter(void); | ||
25 | void exit(void); | ||
26 | phandle finddevice(const char *name); | ||
27 | int getprop(phandle node, const char *name, void *buf, int buflen); | ||
28 | void ofinit(prom_entry entry); | ||
29 | int ofstdio(ihandle *stdin, ihandle *stdout, ihandle *stderr); | ||
30 | int read(ihandle instance, void *buf, int buflen); | ||
31 | void release(void *virt, unsigned int size); | ||
32 | int write(ihandle instance, void *buf, int buflen); | ||
33 | |||
34 | /* inlines */ | ||
35 | |||
36 | extern inline void pause(void) | ||
37 | { | ||
38 | enter(); | ||
39 | } | ||
diff --git a/arch/ppc/boot/include/rs6000.h b/arch/ppc/boot/include/rs6000.h new file mode 100644 index 000000000000..433f45084e41 --- /dev/null +++ b/arch/ppc/boot/include/rs6000.h | |||
@@ -0,0 +1,243 @@ | |||
1 | /* IBM RS/6000 "XCOFF" file definitions for BFD. | ||
2 | Copyright (C) 1990, 1991 Free Software Foundation, Inc. | ||
3 | FIXME: Can someone provide a transliteration of this name into ASCII? | ||
4 | Using the following chars caused a compiler warning on HIUX (so I replaced | ||
5 | them with octal escapes), and isn't useful without an understanding of what | ||
6 | character set it is. | ||
7 | Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM | ||
8 | and John Gilmore of Cygnus Support. */ | ||
9 | |||
10 | /********************** FILE HEADER **********************/ | ||
11 | |||
12 | struct external_filehdr { | ||
13 | char f_magic[2]; /* magic number */ | ||
14 | char f_nscns[2]; /* number of sections */ | ||
15 | char f_timdat[4]; /* time & date stamp */ | ||
16 | char f_symptr[4]; /* file pointer to symtab */ | ||
17 | char f_nsyms[4]; /* number of symtab entries */ | ||
18 | char f_opthdr[2]; /* sizeof(optional hdr) */ | ||
19 | char f_flags[2]; /* flags */ | ||
20 | }; | ||
21 | |||
22 | /* IBM RS/6000 */ | ||
23 | #define U802WRMAGIC 0730 /* writeable text segments **chh** */ | ||
24 | #define U802ROMAGIC 0735 /* readonly sharable text segments */ | ||
25 | #define U802TOCMAGIC 0737 /* readonly text segments and TOC */ | ||
26 | |||
27 | #define BADMAG(x) \ | ||
28 | ((x).f_magic != U802ROMAGIC && (x).f_magic != U802WRMAGIC && \ | ||
29 | (x).f_magic != U802TOCMAGIC) | ||
30 | |||
31 | #define FILHDR struct external_filehdr | ||
32 | #define FILHSZ 20 | ||
33 | |||
34 | |||
35 | /********************** AOUT "OPTIONAL HEADER" **********************/ | ||
36 | |||
37 | |||
38 | typedef struct | ||
39 | { | ||
40 | unsigned char magic[2]; /* type of file */ | ||
41 | unsigned char vstamp[2]; /* version stamp */ | ||
42 | unsigned char tsize[4]; /* text size in bytes, padded to FW bdry */ | ||
43 | unsigned char dsize[4]; /* initialized data " " */ | ||
44 | unsigned char bsize[4]; /* uninitialized data " " */ | ||
45 | unsigned char entry[4]; /* entry pt. */ | ||
46 | unsigned char text_start[4]; /* base of text used for this file */ | ||
47 | unsigned char data_start[4]; /* base of data used for this file */ | ||
48 | unsigned char o_toc[4]; /* address of TOC */ | ||
49 | unsigned char o_snentry[2]; /* section number of entry point */ | ||
50 | unsigned char o_sntext[2]; /* section number of .text section */ | ||
51 | unsigned char o_sndata[2]; /* section number of .data section */ | ||
52 | unsigned char o_sntoc[2]; /* section number of TOC */ | ||
53 | unsigned char o_snloader[2]; /* section number of .loader section */ | ||
54 | unsigned char o_snbss[2]; /* section number of .bss section */ | ||
55 | unsigned char o_algntext[2]; /* .text alignment */ | ||
56 | unsigned char o_algndata[2]; /* .data alignment */ | ||
57 | unsigned char o_modtype[2]; /* module type (??) */ | ||
58 | unsigned char o_cputype[2]; /* cpu type */ | ||
59 | unsigned char o_maxstack[4]; /* max stack size (??) */ | ||
60 | unsigned char o_maxdata[4]; /* max data size (??) */ | ||
61 | unsigned char o_resv2[12]; /* reserved */ | ||
62 | } | ||
63 | AOUTHDR; | ||
64 | |||
65 | #define AOUTSZ 72 | ||
66 | #define SMALL_AOUTSZ (28) | ||
67 | #define AOUTHDRSZ 72 | ||
68 | |||
69 | #define RS6K_AOUTHDR_OMAGIC 0x0107 /* old: text & data writeable */ | ||
70 | #define RS6K_AOUTHDR_NMAGIC 0x0108 /* new: text r/o, data r/w */ | ||
71 | #define RS6K_AOUTHDR_ZMAGIC 0x010B /* paged: text r/o, both page-aligned */ | ||
72 | |||
73 | |||
74 | /********************** SECTION HEADER **********************/ | ||
75 | |||
76 | |||
77 | struct external_scnhdr { | ||
78 | char s_name[8]; /* section name */ | ||
79 | char s_paddr[4]; /* physical address, aliased s_nlib */ | ||
80 | char s_vaddr[4]; /* virtual address */ | ||
81 | char s_size[4]; /* section size */ | ||
82 | char s_scnptr[4]; /* file ptr to raw data for section */ | ||
83 | char s_relptr[4]; /* file ptr to relocation */ | ||
84 | char s_lnnoptr[4]; /* file ptr to line numbers */ | ||
85 | char s_nreloc[2]; /* number of relocation entries */ | ||
86 | char s_nlnno[2]; /* number of line number entries*/ | ||
87 | char s_flags[4]; /* flags */ | ||
88 | }; | ||
89 | |||
90 | /* | ||
91 | * names of "special" sections | ||
92 | */ | ||
93 | #define _TEXT ".text" | ||
94 | #define _DATA ".data" | ||
95 | #define _BSS ".bss" | ||
96 | #define _PAD ".pad" | ||
97 | #define _LOADER ".loader" | ||
98 | |||
99 | #define SCNHDR struct external_scnhdr | ||
100 | #define SCNHSZ 40 | ||
101 | |||
102 | /* XCOFF uses a special .loader section with type STYP_LOADER. */ | ||
103 | #define STYP_LOADER 0x1000 | ||
104 | |||
105 | /* XCOFF uses a special .debug section with type STYP_DEBUG. */ | ||
106 | #define STYP_DEBUG 0x2000 | ||
107 | |||
108 | /* XCOFF handles line number or relocation overflow by creating | ||
109 | another section header with STYP_OVRFLO set. */ | ||
110 | #define STYP_OVRFLO 0x8000 | ||
111 | |||
112 | /********************** LINE NUMBERS **********************/ | ||
113 | |||
114 | /* 1 line number entry for every "breakpointable" source line in a section. | ||
115 | * Line numbers are grouped on a per function basis; first entry in a function | ||
116 | * grouping will have l_lnno = 0 and in place of physical address will be the | ||
117 | * symbol table index of the function name. | ||
118 | */ | ||
119 | struct external_lineno { | ||
120 | union { | ||
121 | char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ | ||
122 | char l_paddr[4]; /* (physical) address of line number */ | ||
123 | } l_addr; | ||
124 | char l_lnno[2]; /* line number */ | ||
125 | }; | ||
126 | |||
127 | |||
128 | #define LINENO struct external_lineno | ||
129 | #define LINESZ 6 | ||
130 | |||
131 | |||
132 | /********************** SYMBOLS **********************/ | ||
133 | |||
134 | #define E_SYMNMLEN 8 /* # characters in a symbol name */ | ||
135 | #define E_FILNMLEN 14 /* # characters in a file name */ | ||
136 | #define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ | ||
137 | |||
138 | struct external_syment | ||
139 | { | ||
140 | union { | ||
141 | char e_name[E_SYMNMLEN]; | ||
142 | struct { | ||
143 | char e_zeroes[4]; | ||
144 | char e_offset[4]; | ||
145 | } e; | ||
146 | } e; | ||
147 | char e_value[4]; | ||
148 | char e_scnum[2]; | ||
149 | char e_type[2]; | ||
150 | char e_sclass[1]; | ||
151 | char e_numaux[1]; | ||
152 | }; | ||
153 | |||
154 | |||
155 | |||
156 | #define N_BTMASK (017) | ||
157 | #define N_TMASK (060) | ||
158 | #define N_BTSHFT (4) | ||
159 | #define N_TSHIFT (2) | ||
160 | |||
161 | |||
162 | union external_auxent { | ||
163 | struct { | ||
164 | char x_tagndx[4]; /* str, un, or enum tag indx */ | ||
165 | union { | ||
166 | struct { | ||
167 | char x_lnno[2]; /* declaration line number */ | ||
168 | char x_size[2]; /* str/union/array size */ | ||
169 | } x_lnsz; | ||
170 | char x_fsize[4]; /* size of function */ | ||
171 | } x_misc; | ||
172 | union { | ||
173 | struct { /* if ISFCN, tag, or .bb */ | ||
174 | char x_lnnoptr[4]; /* ptr to fcn line # */ | ||
175 | char x_endndx[4]; /* entry ndx past block end */ | ||
176 | } x_fcn; | ||
177 | struct { /* if ISARY, up to 4 dimen. */ | ||
178 | char x_dimen[E_DIMNUM][2]; | ||
179 | } x_ary; | ||
180 | } x_fcnary; | ||
181 | char x_tvndx[2]; /* tv index */ | ||
182 | } x_sym; | ||
183 | |||
184 | union { | ||
185 | char x_fname[E_FILNMLEN]; | ||
186 | struct { | ||
187 | char x_zeroes[4]; | ||
188 | char x_offset[4]; | ||
189 | } x_n; | ||
190 | } x_file; | ||
191 | |||
192 | struct { | ||
193 | char x_scnlen[4]; /* section length */ | ||
194 | char x_nreloc[2]; /* # relocation entries */ | ||
195 | char x_nlinno[2]; /* # line numbers */ | ||
196 | } x_scn; | ||
197 | |||
198 | struct { | ||
199 | char x_tvfill[4]; /* tv fill value */ | ||
200 | char x_tvlen[2]; /* length of .tv */ | ||
201 | char x_tvran[2][2]; /* tv range */ | ||
202 | } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ | ||
203 | |||
204 | struct { | ||
205 | unsigned char x_scnlen[4]; | ||
206 | unsigned char x_parmhash[4]; | ||
207 | unsigned char x_snhash[2]; | ||
208 | unsigned char x_smtyp[1]; | ||
209 | unsigned char x_smclas[1]; | ||
210 | unsigned char x_stab[4]; | ||
211 | unsigned char x_snstab[2]; | ||
212 | } x_csect; | ||
213 | |||
214 | }; | ||
215 | |||
216 | #define SYMENT struct external_syment | ||
217 | #define SYMESZ 18 | ||
218 | #define AUXENT union external_auxent | ||
219 | #define AUXESZ 18 | ||
220 | #define DBXMASK 0x80 /* for dbx storage mask */ | ||
221 | #define SYMNAME_IN_DEBUG(symptr) ((symptr)->n_sclass & DBXMASK) | ||
222 | |||
223 | |||
224 | |||
225 | /********************** RELOCATION DIRECTIVES **********************/ | ||
226 | |||
227 | |||
228 | struct external_reloc { | ||
229 | char r_vaddr[4]; | ||
230 | char r_symndx[4]; | ||
231 | char r_size[1]; | ||
232 | char r_type[1]; | ||
233 | }; | ||
234 | |||
235 | |||
236 | #define RELOC struct external_reloc | ||
237 | #define RELSZ 10 | ||
238 | |||
239 | #define DEFAULT_DATA_SECTION_ALIGNMENT 4 | ||
240 | #define DEFAULT_BSS_SECTION_ALIGNMENT 4 | ||
241 | #define DEFAULT_TEXT_SECTION_ALIGNMENT 4 | ||
242 | /* For new sections we havn't heard of before */ | ||
243 | #define DEFAULT_SECTION_ALIGNMENT 4 | ||
diff --git a/arch/ppc/boot/include/serial.h b/arch/ppc/boot/include/serial.h new file mode 100644 index 000000000000..d710eabb4256 --- /dev/null +++ b/arch/ppc/boot/include/serial.h | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * A really private header file for the (dumb) serial driver in arch/ppc/boot | ||
3 | * | ||
4 | * Shamelessly taken from include/linux/serialP.h: | ||
5 | * | ||
6 | * Copyright (C) 1997 by Theodore Ts'o. | ||
7 | * | ||
8 | * Redistribution of this file is permitted under the terms of the GNU | ||
9 | * Public License (GPL) | ||
10 | */ | ||
11 | |||
12 | #ifndef _PPC_BOOT_SERIALP_H | ||
13 | #define _PPC_BOOT_SERIALP_H | ||
14 | |||
15 | /* | ||
16 | * This is our internal structure for each serial port's state. | ||
17 | * | ||
18 | * Many fields are paralleled by the structure used by the serial_struct | ||
19 | * structure. | ||
20 | * | ||
21 | * Given that this is how SERIAL_PORT_DFNS are done, and that we need | ||
22 | * to use a few of their fields, we need to have our own copy of it. | ||
23 | */ | ||
24 | struct serial_state { | ||
25 | int magic; | ||
26 | int baud_base; | ||
27 | unsigned long port; | ||
28 | int irq; | ||
29 | int flags; | ||
30 | int hub6; | ||
31 | int type; | ||
32 | int line; | ||
33 | int revision; /* Chip revision (950) */ | ||
34 | int xmit_fifo_size; | ||
35 | int custom_divisor; | ||
36 | int count; | ||
37 | u8 *iomem_base; | ||
38 | u16 iomem_reg_shift; | ||
39 | unsigned short close_delay; | ||
40 | unsigned short closing_wait; /* time to wait before closing */ | ||
41 | unsigned long icount; | ||
42 | int io_type; | ||
43 | void *info; | ||
44 | void *dev; | ||
45 | }; | ||
46 | #endif /* _PPC_BOOT_SERIAL_H */ | ||
diff --git a/arch/ppc/boot/ld.script b/arch/ppc/boot/ld.script new file mode 100644 index 000000000000..6ee602d8b6a0 --- /dev/null +++ b/arch/ppc/boot/ld.script | |||
@@ -0,0 +1,88 @@ | |||
1 | OUTPUT_ARCH(powerpc) | ||
2 | SECTIONS | ||
3 | { | ||
4 | /* Read-only sections, merged into text segment: */ | ||
5 | . = + SIZEOF_HEADERS; | ||
6 | .interp : { *(.interp) } | ||
7 | .hash : { *(.hash) } | ||
8 | .dynsym : { *(.dynsym) } | ||
9 | .dynstr : { *(.dynstr) } | ||
10 | .rel.text : { *(.rel.text) } | ||
11 | .rela.text : { *(.rela.text) } | ||
12 | .rel.data : { *(.rel.data) } | ||
13 | .rela.data : { *(.rela.data) } | ||
14 | .rel.rodata : { *(.rel.rodata) } | ||
15 | .rela.rodata : { *(.rela.rodata) } | ||
16 | .rel.got : { *(.rel.got) } | ||
17 | .rela.got : { *(.rela.got) } | ||
18 | .rel.ctors : { *(.rel.ctors) } | ||
19 | .rela.ctors : { *(.rela.ctors) } | ||
20 | .rel.dtors : { *(.rel.dtors) } | ||
21 | .rela.dtors : { *(.rela.dtors) } | ||
22 | .rel.bss : { *(.rel.bss) } | ||
23 | .rela.bss : { *(.rela.bss) } | ||
24 | .rel.plt : { *(.rel.plt) } | ||
25 | .rela.plt : { *(.rela.plt) } | ||
26 | .plt : { *(.plt) } | ||
27 | .text : | ||
28 | { | ||
29 | *(.text) | ||
30 | *(.fixup) | ||
31 | __relocate_start = .; | ||
32 | *(.relocate_code) | ||
33 | __relocate_end = .; | ||
34 | } | ||
35 | _etext = .; | ||
36 | PROVIDE (etext = .); | ||
37 | |||
38 | /* Read-write section, merged into data segment: */ | ||
39 | . = ALIGN(4096); | ||
40 | .data : | ||
41 | { | ||
42 | *(.data) | ||
43 | *(.data1) | ||
44 | *(.data.boot) | ||
45 | *(.sdata) | ||
46 | *(.sdata2) | ||
47 | *(.got.plt) *(.got) | ||
48 | *(.dynamic) | ||
49 | *(.rodata) | ||
50 | *(.rodata.*) | ||
51 | *(.rodata1) | ||
52 | *(.got1) | ||
53 | __image_begin = .; | ||
54 | *(.image) | ||
55 | __image_end = .; | ||
56 | . = ALIGN(4096); | ||
57 | __ramdisk_begin = .; | ||
58 | *(.ramdisk) | ||
59 | __ramdisk_end = .; | ||
60 | . = ALIGN(4096); | ||
61 | __sysmap_begin = .; | ||
62 | *(.sysmap) | ||
63 | __sysmap_end = .; | ||
64 | CONSTRUCTORS | ||
65 | } | ||
66 | _edata = .; | ||
67 | PROVIDE (edata = .); | ||
68 | |||
69 | . = ALIGN(4096); | ||
70 | __bss_start = .; | ||
71 | .bss : | ||
72 | { | ||
73 | *(.sbss) *(.scommon) | ||
74 | *(.dynbss) | ||
75 | *(.bss) | ||
76 | *(COMMON) | ||
77 | } | ||
78 | _end = . ; | ||
79 | PROVIDE (end = .); | ||
80 | |||
81 | /DISCARD/ : { | ||
82 | *(__ksymtab) | ||
83 | *(__ksymtab_strings) | ||
84 | *(__bug_table) | ||
85 | *(__kcrctab) | ||
86 | } | ||
87 | |||
88 | } | ||
diff --git a/arch/ppc/boot/lib/Makefile b/arch/ppc/boot/lib/Makefile new file mode 100644 index 000000000000..d4077e69086f --- /dev/null +++ b/arch/ppc/boot/lib/Makefile | |||
@@ -0,0 +1,23 @@ | |||
1 | # | ||
2 | # Makefile for some libs needed by zImage. | ||
3 | # | ||
4 | |||
5 | CFLAGS_kbd.o := -Idrivers/char | ||
6 | CFLAGS_vreset.o := -I$(srctree)/arch/ppc/boot/include | ||
7 | |||
8 | zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c | ||
9 | |||
10 | lib-y += $(zlib:.c=.o) div64.o | ||
11 | lib-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o | ||
12 | |||
13 | |||
14 | # zlib files needs header from their original place | ||
15 | EXTRA_CFLAGS += -Ilib/zlib_inflate | ||
16 | |||
17 | quiet_cmd_copy_zlib = COPY $@ | ||
18 | cmd_copy_zlib = cat $< > $@ | ||
19 | |||
20 | $(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/% | ||
21 | $(call cmd,copy_zlib) | ||
22 | |||
23 | clean-files := $(zlib) | ||
diff --git a/arch/ppc/boot/lib/div64.S b/arch/ppc/boot/lib/div64.S new file mode 100644 index 000000000000..3527569e9926 --- /dev/null +++ b/arch/ppc/boot/lib/div64.S | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * Divide a 64-bit unsigned number by a 32-bit unsigned number. | ||
3 | * This routine assumes that the top 32 bits of the dividend are | ||
4 | * non-zero to start with. | ||
5 | * On entry, r3 points to the dividend, which get overwritten with | ||
6 | * the 64-bit quotient, and r4 contains the divisor. | ||
7 | * On exit, r3 contains the remainder. | ||
8 | * | ||
9 | * Copyright (C) 2002 Paul Mackerras, IBM Corp. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version | ||
14 | * 2 of the License, or (at your option) any later version. | ||
15 | */ | ||
16 | #include <asm/ppc_asm.h> | ||
17 | #include <asm/processor.h> | ||
18 | |||
19 | _GLOBAL(__div64_32) | ||
20 | lwz r5,0(r3) # get the dividend into r5/r6 | ||
21 | lwz r6,4(r3) | ||
22 | cmplw r5,r4 | ||
23 | li r7,0 | ||
24 | li r8,0 | ||
25 | blt 1f | ||
26 | divwu r7,r5,r4 # if dividend.hi >= divisor, | ||
27 | mullw r0,r7,r4 # quotient.hi = dividend.hi / divisor | ||
28 | subf. r5,r0,r5 # dividend.hi %= divisor | ||
29 | beq 3f | ||
30 | 1: mr r11,r5 # here dividend.hi != 0 | ||
31 | andis. r0,r5,0xc000 | ||
32 | bne 2f | ||
33 | cntlzw r0,r5 # we are shifting the dividend right | ||
34 | li r10,-1 # to make it < 2^32, and shifting | ||
35 | srw r10,r10,r0 # the divisor right the same amount, | ||
36 | add r9,r4,r10 # rounding up (so the estimate cannot | ||
37 | andc r11,r6,r10 # ever be too large, only too small) | ||
38 | andc r9,r9,r10 | ||
39 | or r11,r5,r11 | ||
40 | rotlw r9,r9,r0 | ||
41 | rotlw r11,r11,r0 | ||
42 | divwu r11,r11,r9 # then we divide the shifted quantities | ||
43 | 2: mullw r10,r11,r4 # to get an estimate of the quotient, | ||
44 | mulhwu r9,r11,r4 # multiply the estimate by the divisor, | ||
45 | subfc r6,r10,r6 # take the product from the divisor, | ||
46 | add r8,r8,r11 # and add the estimate to the accumulated | ||
47 | subfe. r5,r9,r5 # quotient | ||
48 | bne 1b | ||
49 | 3: cmplw r6,r4 | ||
50 | blt 4f | ||
51 | divwu r0,r6,r4 # perform the remaining 32-bit division | ||
52 | mullw r10,r0,r4 # and get the remainder | ||
53 | add r8,r8,r0 | ||
54 | subf r6,r10,r6 | ||
55 | 4: stw r7,0(r3) # return the quotient in *r3 | ||
56 | stw r8,4(r3) | ||
57 | mr r3,r6 # return the remainder in r3 | ||
58 | blr | ||
diff --git a/arch/ppc/boot/lib/kbd.c b/arch/ppc/boot/lib/kbd.c new file mode 100644 index 000000000000..3931727434de --- /dev/null +++ b/arch/ppc/boot/lib/kbd.c | |||
@@ -0,0 +1,248 @@ | |||
1 | #include <linux/keyboard.h> | ||
2 | |||
3 | #include "defkeymap.c" /* yeah I know it's bad -- Cort */ | ||
4 | |||
5 | |||
6 | unsigned char shfts, ctls, alts, caps; | ||
7 | |||
8 | #define KBDATAP 0x60 /* kbd data port */ | ||
9 | #define KBSTATUSPORT 0x61 /* kbd status */ | ||
10 | #define KBSTATP 0x64 /* kbd status port */ | ||
11 | #define KBINRDY 0x01 | ||
12 | #define KBOUTRDY 0x02 | ||
13 | |||
14 | extern unsigned char inb(int port); | ||
15 | extern void outb(int port, char val); | ||
16 | extern void puts(const char *); | ||
17 | extern void puthex(unsigned long val); | ||
18 | extern void udelay(long x); | ||
19 | |||
20 | static int kbd(int noblock) | ||
21 | { | ||
22 | unsigned char dt, brk, val; | ||
23 | unsigned code; | ||
24 | loop: | ||
25 | if (noblock) { | ||
26 | if ((inb(KBSTATP) & KBINRDY) == 0) | ||
27 | return (-1); | ||
28 | } else while((inb(KBSTATP) & KBINRDY) == 0) ; | ||
29 | |||
30 | dt = inb(KBDATAP); | ||
31 | |||
32 | brk = dt & 0x80; /* brk == 1 on key release */ | ||
33 | dt = dt & 0x7f; /* keycode */ | ||
34 | |||
35 | if (shfts) | ||
36 | code = shift_map[dt]; | ||
37 | else if (ctls) | ||
38 | code = ctrl_map[dt]; | ||
39 | else | ||
40 | code = plain_map[dt]; | ||
41 | |||
42 | val = KVAL(code); | ||
43 | switch (KTYP(code) & 0x0f) { | ||
44 | case KT_LATIN: | ||
45 | if (brk) | ||
46 | break; | ||
47 | if (alts) | ||
48 | val |= 0x80; | ||
49 | if (val == 0x7f) /* map delete to backspace */ | ||
50 | val = '\b'; | ||
51 | return val; | ||
52 | |||
53 | case KT_LETTER: | ||
54 | if (brk) | ||
55 | break; | ||
56 | if (caps) | ||
57 | val -= 'a'-'A'; | ||
58 | return val; | ||
59 | |||
60 | case KT_SPEC: | ||
61 | if (brk) | ||
62 | break; | ||
63 | if (val == KVAL(K_CAPS)) | ||
64 | caps = !caps; | ||
65 | else if (val == KVAL(K_ENTER)) { | ||
66 | enter: /* Wait for key up */ | ||
67 | while (1) { | ||
68 | while((inb(KBSTATP) & KBINRDY) == 0) ; | ||
69 | dt = inb(KBDATAP); | ||
70 | if (dt & 0x80) /* key up */ break; | ||
71 | } | ||
72 | return 10; | ||
73 | } | ||
74 | break; | ||
75 | |||
76 | case KT_PAD: | ||
77 | if (brk) | ||
78 | break; | ||
79 | if (val < 10) | ||
80 | return val; | ||
81 | if (val == KVAL(K_PENTER)) | ||
82 | goto enter; | ||
83 | break; | ||
84 | |||
85 | case KT_SHIFT: | ||
86 | switch (val) { | ||
87 | case KG_SHIFT: | ||
88 | case KG_SHIFTL: | ||
89 | case KG_SHIFTR: | ||
90 | shfts = brk ? 0 : 1; | ||
91 | break; | ||
92 | case KG_ALT: | ||
93 | case KG_ALTGR: | ||
94 | alts = brk ? 0 : 1; | ||
95 | break; | ||
96 | case KG_CTRL: | ||
97 | case KG_CTRLL: | ||
98 | case KG_CTRLR: | ||
99 | ctls = brk ? 0 : 1; | ||
100 | break; | ||
101 | } | ||
102 | break; | ||
103 | |||
104 | case KT_LOCK: | ||
105 | switch (val) { | ||
106 | case KG_SHIFT: | ||
107 | case KG_SHIFTL: | ||
108 | case KG_SHIFTR: | ||
109 | if (brk) | ||
110 | shfts = !shfts; | ||
111 | break; | ||
112 | case KG_ALT: | ||
113 | case KG_ALTGR: | ||
114 | if (brk) | ||
115 | alts = !alts; | ||
116 | break; | ||
117 | case KG_CTRL: | ||
118 | case KG_CTRLL: | ||
119 | case KG_CTRLR: | ||
120 | if (brk) | ||
121 | ctls = !ctls; | ||
122 | break; | ||
123 | } | ||
124 | break; | ||
125 | } | ||
126 | if (brk) return (-1); /* Ignore initial 'key up' codes */ | ||
127 | goto loop; | ||
128 | } | ||
129 | |||
130 | static int __kbdreset(void) | ||
131 | { | ||
132 | unsigned char c; | ||
133 | int i, t; | ||
134 | |||
135 | /* flush input queue */ | ||
136 | t = 2000; | ||
137 | while ((inb(KBSTATP) & KBINRDY)) | ||
138 | { | ||
139 | (void)inb(KBDATAP); | ||
140 | if (--t == 0) | ||
141 | return 1; | ||
142 | } | ||
143 | /* Send self-test */ | ||
144 | t = 20000; | ||
145 | while (inb(KBSTATP) & KBOUTRDY) | ||
146 | if (--t == 0) | ||
147 | return 2; | ||
148 | outb(KBSTATP,0xAA); | ||
149 | t = 200000; | ||
150 | while ((inb(KBSTATP) & KBINRDY) == 0) /* wait input ready */ | ||
151 | if (--t == 0) | ||
152 | return 3; | ||
153 | if ((c = inb(KBDATAP)) != 0x55) | ||
154 | { | ||
155 | puts("Keyboard self test failed - result:"); | ||
156 | puthex(c); | ||
157 | puts("\n"); | ||
158 | } | ||
159 | /* Enable interrupts and keyboard controller */ | ||
160 | t = 20000; | ||
161 | while (inb(KBSTATP) & KBOUTRDY) | ||
162 | if (--t == 0) return 4; | ||
163 | outb(KBSTATP,0x60); | ||
164 | t = 20000; | ||
165 | while (inb(KBSTATP) & KBOUTRDY) | ||
166 | if (--t == 0) return 5; | ||
167 | outb(KBDATAP,0x45); | ||
168 | for (i = 0; i < 10000; i++) udelay(1); | ||
169 | |||
170 | t = 20000; | ||
171 | while (inb(KBSTATP) & KBOUTRDY) | ||
172 | if (--t == 0) return 6; | ||
173 | outb(KBSTATP,0x20); | ||
174 | t = 200000; | ||
175 | while ((inb(KBSTATP) & KBINRDY) == 0) /* wait input ready */ | ||
176 | if (--t == 0) return 7; | ||
177 | if (! (inb(KBDATAP) & 0x40)) { | ||
178 | /* | ||
179 | * Quote from PS/2 System Reference Manual: | ||
180 | * | ||
181 | * "Address hex 0060 and address hex 0064 should be | ||
182 | * written only when the input-buffer-full bit and | ||
183 | * output-buffer-full bit in the Controller Status | ||
184 | * register are set 0." (KBINRDY and KBOUTRDY) | ||
185 | */ | ||
186 | t = 200000; | ||
187 | while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) | ||
188 | if (--t == 0) return 8; | ||
189 | outb(KBDATAP,0xF0); | ||
190 | t = 200000; | ||
191 | while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) | ||
192 | if (--t == 0) return 9; | ||
193 | outb(KBDATAP,0x01); | ||
194 | } | ||
195 | t = 20000; | ||
196 | while (inb(KBSTATP) & KBOUTRDY) | ||
197 | if (--t == 0) return 10; | ||
198 | outb(KBSTATP,0xAE); | ||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | static void kbdreset(void) | ||
203 | { | ||
204 | int ret = __kbdreset(); | ||
205 | |||
206 | if (ret) { | ||
207 | puts("__kbdreset failed: "); | ||
208 | puthex(ret); | ||
209 | puts("\n"); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | /* We have to actually read the keyboard when CRT_tstc is called, | ||
214 | * since the pending data might be a key release code, and therefore | ||
215 | * not valid data. In this case, kbd() will return -1, even though there's | ||
216 | * data to be read. Of course, we might actually read a valid key press, | ||
217 | * in which case it gets queued into key_pending for use by CRT_getc. | ||
218 | */ | ||
219 | |||
220 | static int kbd_reset = 0; | ||
221 | |||
222 | static int key_pending = -1; | ||
223 | |||
224 | int CRT_getc(void) | ||
225 | { | ||
226 | int c; | ||
227 | if (!kbd_reset) {kbdreset(); kbd_reset++; } | ||
228 | |||
229 | if (key_pending != -1) { | ||
230 | c = key_pending; | ||
231 | key_pending = -1; | ||
232 | return c; | ||
233 | } else { | ||
234 | while ((c = kbd(0)) == 0) ; | ||
235 | return c; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | int CRT_tstc(void) | ||
240 | { | ||
241 | if (!kbd_reset) {kbdreset(); kbd_reset++; } | ||
242 | |||
243 | while (key_pending == -1 && ((inb(KBSTATP) & KBINRDY) != 0)) { | ||
244 | key_pending = kbd(1); | ||
245 | } | ||
246 | |||
247 | return (key_pending != -1); | ||
248 | } | ||
diff --git a/arch/ppc/boot/lib/vreset.c b/arch/ppc/boot/lib/vreset.c new file mode 100644 index 000000000000..463ba001fb9b --- /dev/null +++ b/arch/ppc/boot/lib/vreset.c | |||
@@ -0,0 +1,805 @@ | |||
1 | /* | ||
2 | * vreset.c | ||
3 | * | ||
4 | * Initialize the VGA control registers to 80x25 text mode. | ||
5 | * | ||
6 | * Adapted from a program by: | ||
7 | * Steve Sellgren | ||
8 | * San Francisco Indigo Company | ||
9 | * sfindigo!sellgren@uunet.uu.net | ||
10 | * | ||
11 | * Original concept by: | ||
12 | * Gary Thomas <gdt@linuxppc.org> | ||
13 | * Adapted for Moto boxes by: | ||
14 | * Pat Kane & Mark Scott, 1996 | ||
15 | * Adapted for IBM portables by: | ||
16 | * Takeshi Ishimoto | ||
17 | * Multi-console support: | ||
18 | * Terje Malmedal <terje.malmedal@usit.uio.no> | ||
19 | */ | ||
20 | |||
21 | #include "iso_font.h" | ||
22 | #include "nonstdio.h" | ||
23 | |||
24 | extern char *vidmem; | ||
25 | extern int lines, cols; | ||
26 | struct VaRegs; | ||
27 | |||
28 | /* | ||
29 | * VGA Register | ||
30 | */ | ||
31 | struct VgaRegs | ||
32 | { | ||
33 | unsigned short io_port; | ||
34 | unsigned char io_index; | ||
35 | unsigned char io_value; | ||
36 | }; | ||
37 | |||
38 | void unlockVideo(int slot); | ||
39 | void setTextRegs(struct VgaRegs *svp); | ||
40 | void setTextCLUT(int shift); | ||
41 | void clearVideoMemory(void); | ||
42 | void loadFont(unsigned char *ISA_mem); | ||
43 | |||
44 | static void mdelay(int ms) | ||
45 | { | ||
46 | for (; ms > 0; --ms) | ||
47 | udelay(1000); | ||
48 | } | ||
49 | |||
50 | /* | ||
51 | * Default console text mode registers used to reset | ||
52 | * graphics adapter. | ||
53 | */ | ||
54 | #define NREGS 54 | ||
55 | #define ENDMK 0xFFFF /* End marker */ | ||
56 | |||
57 | #define S3Vendor 0x5333 | ||
58 | #define CirrusVendor 0x1013 | ||
59 | #define DiamondVendor 0x100E | ||
60 | #define MatroxVendor 0x102B | ||
61 | #define ParadiseVendor 0x101C | ||
62 | |||
63 | struct VgaRegs GenVgaTextRegs[NREGS+1] = { | ||
64 | /* port index value */ | ||
65 | /* SR Regs */ | ||
66 | { 0x3c4, 0x1, 0x0 }, | ||
67 | { 0x3c4, 0x2, 0x3 }, | ||
68 | { 0x3c4, 0x3, 0x0 }, | ||
69 | { 0x3c4, 0x4, 0x2 }, | ||
70 | /* CR Regs */ | ||
71 | { 0x3d4, 0x0, 0x5f }, | ||
72 | { 0x3d4, 0x1, 0x4f }, | ||
73 | { 0x3d4, 0x2, 0x50 }, | ||
74 | { 0x3d4, 0x3, 0x82 }, | ||
75 | { 0x3d4, 0x4, 0x55 }, | ||
76 | { 0x3d4, 0x5, 0x81 }, | ||
77 | { 0x3d4, 0x6, 0xbf }, | ||
78 | { 0x3d4, 0x7, 0x1f }, | ||
79 | { 0x3d4, 0x8, 0x00 }, | ||
80 | { 0x3d4, 0x9, 0x4f }, | ||
81 | { 0x3d4, 0xa, 0x0d }, | ||
82 | { 0x3d4, 0xb, 0x0e }, | ||
83 | { 0x3d4, 0xc, 0x00 }, | ||
84 | { 0x3d4, 0xd, 0x00 }, | ||
85 | { 0x3d4, 0xe, 0x00 }, | ||
86 | { 0x3d4, 0xf, 0x00 }, | ||
87 | { 0x3d4, 0x10, 0x9c }, | ||
88 | { 0x3d4, 0x11, 0x8e }, | ||
89 | { 0x3d4, 0x12, 0x8f }, | ||
90 | { 0x3d4, 0x13, 0x28 }, | ||
91 | { 0x3d4, 0x14, 0x1f }, | ||
92 | { 0x3d4, 0x15, 0x96 }, | ||
93 | { 0x3d4, 0x16, 0xb9 }, | ||
94 | { 0x3d4, 0x17, 0xa3 }, | ||
95 | /* GR Regs */ | ||
96 | { 0x3ce, 0x0, 0x0 }, | ||
97 | { 0x3ce, 0x1, 0x0 }, | ||
98 | { 0x3ce, 0x2, 0x0 }, | ||
99 | { 0x3ce, 0x3, 0x0 }, | ||
100 | { 0x3ce, 0x4, 0x0 }, | ||
101 | { 0x3ce, 0x5, 0x10 }, | ||
102 | { 0x3ce, 0x6, 0xe }, | ||
103 | { 0x3ce, 0x7, 0x0 }, | ||
104 | { 0x3ce, 0x8, 0xff }, | ||
105 | { ENDMK } | ||
106 | }; | ||
107 | |||
108 | struct RGBColors | ||
109 | { | ||
110 | unsigned char r, g, b; | ||
111 | }; | ||
112 | |||
113 | /* | ||
114 | * Default console text mode color table. | ||
115 | * These values were obtained by booting Linux with | ||
116 | * text mode firmware & then dumping the registers. | ||
117 | */ | ||
118 | struct RGBColors TextCLUT[256] = | ||
119 | { | ||
120 | /* red green blue */ | ||
121 | { 0x0, 0x0, 0x0 }, | ||
122 | { 0x0, 0x0, 0x2a }, | ||
123 | { 0x0, 0x2a, 0x0 }, | ||
124 | { 0x0, 0x2a, 0x2a }, | ||
125 | { 0x2a, 0x0, 0x0 }, | ||
126 | { 0x2a, 0x0, 0x2a }, | ||
127 | { 0x2a, 0x2a, 0x0 }, | ||
128 | { 0x2a, 0x2a, 0x2a }, | ||
129 | { 0x0, 0x0, 0x15 }, | ||
130 | { 0x0, 0x0, 0x3f }, | ||
131 | { 0x0, 0x2a, 0x15 }, | ||
132 | { 0x0, 0x2a, 0x3f }, | ||
133 | { 0x2a, 0x0, 0x15 }, | ||
134 | { 0x2a, 0x0, 0x3f }, | ||
135 | { 0x2a, 0x2a, 0x15 }, | ||
136 | { 0x2a, 0x2a, 0x3f }, | ||
137 | { 0x0, 0x15, 0x0 }, | ||
138 | { 0x0, 0x15, 0x2a }, | ||
139 | { 0x0, 0x3f, 0x0 }, | ||
140 | { 0x0, 0x3f, 0x2a }, | ||
141 | { 0x2a, 0x15, 0x0 }, | ||
142 | { 0x2a, 0x15, 0x2a }, | ||
143 | { 0x2a, 0x3f, 0x0 }, | ||
144 | { 0x2a, 0x3f, 0x2a }, | ||
145 | { 0x0, 0x15, 0x15 }, | ||
146 | { 0x0, 0x15, 0x3f }, | ||
147 | { 0x0, 0x3f, 0x15 }, | ||
148 | { 0x0, 0x3f, 0x3f }, | ||
149 | { 0x2a, 0x15, 0x15 }, | ||
150 | { 0x2a, 0x15, 0x3f }, | ||
151 | { 0x2a, 0x3f, 0x15 }, | ||
152 | { 0x2a, 0x3f, 0x3f }, | ||
153 | { 0x15, 0x0, 0x0 }, | ||
154 | { 0x15, 0x0, 0x2a }, | ||
155 | { 0x15, 0x2a, 0x0 }, | ||
156 | { 0x15, 0x2a, 0x2a }, | ||
157 | { 0x3f, 0x0, 0x0 }, | ||
158 | { 0x3f, 0x0, 0x2a }, | ||
159 | { 0x3f, 0x2a, 0x0 }, | ||
160 | { 0x3f, 0x2a, 0x2a }, | ||
161 | { 0x15, 0x0, 0x15 }, | ||
162 | { 0x15, 0x0, 0x3f }, | ||
163 | { 0x15, 0x2a, 0x15 }, | ||
164 | { 0x15, 0x2a, 0x3f }, | ||
165 | { 0x3f, 0x0, 0x15 }, | ||
166 | { 0x3f, 0x0, 0x3f }, | ||
167 | { 0x3f, 0x2a, 0x15 }, | ||
168 | { 0x3f, 0x2a, 0x3f }, | ||
169 | { 0x15, 0x15, 0x0 }, | ||
170 | { 0x15, 0x15, 0x2a }, | ||
171 | { 0x15, 0x3f, 0x0 }, | ||
172 | { 0x15, 0x3f, 0x2a }, | ||
173 | { 0x3f, 0x15, 0x0 }, | ||
174 | { 0x3f, 0x15, 0x2a }, | ||
175 | { 0x3f, 0x3f, 0x0 }, | ||
176 | { 0x3f, 0x3f, 0x2a }, | ||
177 | { 0x15, 0x15, 0x15 }, | ||
178 | { 0x15, 0x15, 0x3f }, | ||
179 | { 0x15, 0x3f, 0x15 }, | ||
180 | { 0x15, 0x3f, 0x3f }, | ||
181 | { 0x3f, 0x15, 0x15 }, | ||
182 | { 0x3f, 0x15, 0x3f }, | ||
183 | { 0x3f, 0x3f, 0x15 }, | ||
184 | { 0x3f, 0x3f, 0x3f }, | ||
185 | { 0x39, 0xc, 0x5 }, | ||
186 | { 0x15, 0x2c, 0xf }, | ||
187 | { 0x26, 0x10, 0x3d }, | ||
188 | { 0x29, 0x29, 0x38 }, | ||
189 | { 0x4, 0x1a, 0xe }, | ||
190 | { 0x2, 0x1e, 0x3a }, | ||
191 | { 0x3c, 0x25, 0x33 }, | ||
192 | { 0x3c, 0xc, 0x2c }, | ||
193 | { 0x3f, 0x3, 0x2b }, | ||
194 | { 0x1c, 0x9, 0x13 }, | ||
195 | { 0x25, 0x2a, 0x35 }, | ||
196 | { 0x1e, 0xa, 0x38 }, | ||
197 | { 0x24, 0x8, 0x3 }, | ||
198 | { 0x3, 0xe, 0x36 }, | ||
199 | { 0xc, 0x6, 0x2a }, | ||
200 | { 0x26, 0x3, 0x32 }, | ||
201 | { 0x5, 0x2f, 0x33 }, | ||
202 | { 0x3c, 0x35, 0x2f }, | ||
203 | { 0x2d, 0x26, 0x3e }, | ||
204 | { 0xd, 0xa, 0x10 }, | ||
205 | { 0x25, 0x3c, 0x11 }, | ||
206 | { 0xd, 0x4, 0x2e }, | ||
207 | { 0x5, 0x19, 0x3e }, | ||
208 | { 0xc, 0x13, 0x34 }, | ||
209 | { 0x2b, 0x6, 0x24 }, | ||
210 | { 0x4, 0x3, 0xd }, | ||
211 | { 0x2f, 0x3c, 0xc }, | ||
212 | { 0x2a, 0x37, 0x1f }, | ||
213 | { 0xf, 0x12, 0x38 }, | ||
214 | { 0x38, 0xe, 0x2a }, | ||
215 | { 0x12, 0x2f, 0x19 }, | ||
216 | { 0x29, 0x2e, 0x31 }, | ||
217 | { 0x25, 0x13, 0x3e }, | ||
218 | { 0x33, 0x3e, 0x33 }, | ||
219 | { 0x1d, 0x2c, 0x25 }, | ||
220 | { 0x15, 0x15, 0x5 }, | ||
221 | { 0x32, 0x25, 0x39 }, | ||
222 | { 0x1a, 0x7, 0x1f }, | ||
223 | { 0x13, 0xe, 0x1d }, | ||
224 | { 0x36, 0x17, 0x34 }, | ||
225 | { 0xf, 0x15, 0x23 }, | ||
226 | { 0x2, 0x35, 0xd }, | ||
227 | { 0x15, 0x3f, 0xc }, | ||
228 | { 0x14, 0x2f, 0xf }, | ||
229 | { 0x19, 0x21, 0x3e }, | ||
230 | { 0x27, 0x11, 0x2f }, | ||
231 | { 0x38, 0x3f, 0x3c }, | ||
232 | { 0x36, 0x2d, 0x15 }, | ||
233 | { 0x16, 0x17, 0x2 }, | ||
234 | { 0x1, 0xa, 0x3d }, | ||
235 | { 0x1b, 0x11, 0x3f }, | ||
236 | { 0x21, 0x3c, 0xd }, | ||
237 | { 0x1a, 0x39, 0x3d }, | ||
238 | { 0x8, 0xe, 0xe }, | ||
239 | { 0x22, 0x21, 0x23 }, | ||
240 | { 0x1e, 0x30, 0x5 }, | ||
241 | { 0x1f, 0x22, 0x3d }, | ||
242 | { 0x1e, 0x2f, 0xa }, | ||
243 | { 0x0, 0x1c, 0xe }, | ||
244 | { 0x0, 0x1c, 0x15 }, | ||
245 | { 0x0, 0x1c, 0x1c }, | ||
246 | { 0x0, 0x15, 0x1c }, | ||
247 | { 0x0, 0xe, 0x1c }, | ||
248 | { 0x0, 0x7, 0x1c }, | ||
249 | { 0xe, 0xe, 0x1c }, | ||
250 | { 0x11, 0xe, 0x1c }, | ||
251 | { 0x15, 0xe, 0x1c }, | ||
252 | { 0x18, 0xe, 0x1c }, | ||
253 | { 0x1c, 0xe, 0x1c }, | ||
254 | { 0x1c, 0xe, 0x18 }, | ||
255 | { 0x1c, 0xe, 0x15 }, | ||
256 | { 0x1c, 0xe, 0x11 }, | ||
257 | { 0x1c, 0xe, 0xe }, | ||
258 | { 0x1c, 0x11, 0xe }, | ||
259 | { 0x1c, 0x15, 0xe }, | ||
260 | { 0x1c, 0x18, 0xe }, | ||
261 | { 0x1c, 0x1c, 0xe }, | ||
262 | { 0x18, 0x1c, 0xe }, | ||
263 | { 0x15, 0x1c, 0xe }, | ||
264 | { 0x11, 0x1c, 0xe }, | ||
265 | { 0xe, 0x1c, 0xe }, | ||
266 | { 0xe, 0x1c, 0x11 }, | ||
267 | { 0xe, 0x1c, 0x15 }, | ||
268 | { 0xe, 0x1c, 0x18 }, | ||
269 | { 0xe, 0x1c, 0x1c }, | ||
270 | { 0xe, 0x18, 0x1c }, | ||
271 | { 0xe, 0x15, 0x1c }, | ||
272 | { 0xe, 0x11, 0x1c }, | ||
273 | { 0x14, 0x14, 0x1c }, | ||
274 | { 0x16, 0x14, 0x1c }, | ||
275 | { 0x18, 0x14, 0x1c }, | ||
276 | { 0x1a, 0x14, 0x1c }, | ||
277 | { 0x1c, 0x14, 0x1c }, | ||
278 | { 0x1c, 0x14, 0x1a }, | ||
279 | { 0x1c, 0x14, 0x18 }, | ||
280 | { 0x1c, 0x14, 0x16 }, | ||
281 | { 0x1c, 0x14, 0x14 }, | ||
282 | { 0x1c, 0x16, 0x14 }, | ||
283 | { 0x1c, 0x18, 0x14 }, | ||
284 | { 0x1c, 0x1a, 0x14 }, | ||
285 | { 0x1c, 0x1c, 0x14 }, | ||
286 | { 0x1a, 0x1c, 0x14 }, | ||
287 | { 0x18, 0x1c, 0x14 }, | ||
288 | { 0x16, 0x1c, 0x14 }, | ||
289 | { 0x14, 0x1c, 0x14 }, | ||
290 | { 0x14, 0x1c, 0x16 }, | ||
291 | { 0x14, 0x1c, 0x18 }, | ||
292 | { 0x14, 0x1c, 0x1a }, | ||
293 | { 0x14, 0x1c, 0x1c }, | ||
294 | { 0x14, 0x1a, 0x1c }, | ||
295 | { 0x14, 0x18, 0x1c }, | ||
296 | { 0x14, 0x16, 0x1c }, | ||
297 | { 0x0, 0x0, 0x10 }, | ||
298 | { 0x4, 0x0, 0x10 }, | ||
299 | { 0x8, 0x0, 0x10 }, | ||
300 | { 0xc, 0x0, 0x10 }, | ||
301 | { 0x10, 0x0, 0x10 }, | ||
302 | { 0x10, 0x0, 0xc }, | ||
303 | { 0x10, 0x0, 0x8 }, | ||
304 | { 0x10, 0x0, 0x4 }, | ||
305 | { 0x10, 0x0, 0x0 }, | ||
306 | { 0x10, 0x4, 0x0 }, | ||
307 | { 0x10, 0x8, 0x0 }, | ||
308 | { 0x10, 0xc, 0x0 }, | ||
309 | { 0x10, 0x10, 0x0 }, | ||
310 | { 0xc, 0x10, 0x0 }, | ||
311 | { 0x8, 0x10, 0x0 }, | ||
312 | { 0x4, 0x10, 0x0 }, | ||
313 | { 0x0, 0x10, 0x0 }, | ||
314 | { 0x0, 0x10, 0x4 }, | ||
315 | { 0x0, 0x10, 0x8 }, | ||
316 | { 0x0, 0x10, 0xc }, | ||
317 | { 0x0, 0x10, 0x10 }, | ||
318 | { 0x0, 0xc, 0x10 }, | ||
319 | { 0x0, 0x8, 0x10 }, | ||
320 | { 0x0, 0x4, 0x10 }, | ||
321 | { 0x8, 0x8, 0x10 }, | ||
322 | { 0xa, 0x8, 0x10 }, | ||
323 | { 0xc, 0x8, 0x10 }, | ||
324 | { 0xe, 0x8, 0x10 }, | ||
325 | { 0x10, 0x8, 0x10 }, | ||
326 | { 0x10, 0x8, 0xe }, | ||
327 | { 0x10, 0x8, 0xc }, | ||
328 | { 0x10, 0x8, 0xa }, | ||
329 | { 0x10, 0x8, 0x8 }, | ||
330 | { 0x10, 0xa, 0x8 }, | ||
331 | { 0x10, 0xc, 0x8 }, | ||
332 | { 0x10, 0xe, 0x8 }, | ||
333 | { 0x10, 0x10, 0x8 }, | ||
334 | { 0xe, 0x10, 0x8 }, | ||
335 | { 0xc, 0x10, 0x8 }, | ||
336 | { 0xa, 0x10, 0x8 }, | ||
337 | { 0x8, 0x10, 0x8 }, | ||
338 | { 0x8, 0x10, 0xa }, | ||
339 | { 0x8, 0x10, 0xc }, | ||
340 | { 0x8, 0x10, 0xe }, | ||
341 | { 0x8, 0x10, 0x10 }, | ||
342 | { 0x8, 0xe, 0x10 }, | ||
343 | { 0x8, 0xc, 0x10 }, | ||
344 | { 0x8, 0xa, 0x10 }, | ||
345 | { 0xb, 0xb, 0x10 }, | ||
346 | { 0xc, 0xb, 0x10 }, | ||
347 | { 0xd, 0xb, 0x10 }, | ||
348 | { 0xf, 0xb, 0x10 }, | ||
349 | { 0x10, 0xb, 0x10 }, | ||
350 | { 0x10, 0xb, 0xf }, | ||
351 | { 0x10, 0xb, 0xd }, | ||
352 | { 0x10, 0xb, 0xc }, | ||
353 | { 0x10, 0xb, 0xb }, | ||
354 | { 0x10, 0xc, 0xb }, | ||
355 | { 0x10, 0xd, 0xb }, | ||
356 | { 0x10, 0xf, 0xb }, | ||
357 | { 0x10, 0x10, 0xb }, | ||
358 | { 0xf, 0x10, 0xb }, | ||
359 | { 0xd, 0x10, 0xb }, | ||
360 | { 0xc, 0x10, 0xb }, | ||
361 | { 0xb, 0x10, 0xb }, | ||
362 | { 0xb, 0x10, 0xc }, | ||
363 | { 0xb, 0x10, 0xd }, | ||
364 | { 0xb, 0x10, 0xf }, | ||
365 | { 0xb, 0x10, 0x10 }, | ||
366 | { 0xb, 0xf, 0x10 }, | ||
367 | { 0xb, 0xd, 0x10 }, | ||
368 | { 0xb, 0xc, 0x10 }, | ||
369 | { 0x0, 0x0, 0x0 }, | ||
370 | { 0x0, 0x0, 0x0 }, | ||
371 | { 0x0, 0x0, 0x0 }, | ||
372 | { 0x0, 0x0, 0x0 }, | ||
373 | { 0x0, 0x0, 0x0 }, | ||
374 | { 0x0, 0x0, 0x0 }, | ||
375 | { 0x0, 0x0, 0x0 } | ||
376 | }; | ||
377 | |||
378 | unsigned char AC[21] = { | ||
379 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, | ||
380 | 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, | ||
381 | 0x0C, 0x00, 0x0F, 0x08, 0x00}; | ||
382 | |||
383 | static int scanPCI(int start_slt); | ||
384 | static int PCIVendor(int); | ||
385 | #ifdef DEBUG | ||
386 | static void printslots(void); | ||
387 | #endif | ||
388 | extern void puthex(unsigned long); | ||
389 | extern void puts(const char *); | ||
390 | static void unlockS3(void); | ||
391 | |||
392 | static inline void | ||
393 | outw(int port, unsigned short val) | ||
394 | { | ||
395 | outb(port, val >> 8); | ||
396 | outb(port+1, val); | ||
397 | } | ||
398 | |||
399 | int | ||
400 | vga_init(unsigned char *ISA_mem) | ||
401 | { | ||
402 | int slot; | ||
403 | struct VgaRegs *VgaTextRegs; | ||
404 | |||
405 | /* See if VGA already in TEXT mode - exit if so! */ | ||
406 | outb(0x3CE, 0x06); | ||
407 | if ((inb(0x3CF) & 0x01) == 0){ | ||
408 | puts("VGA already in text mode\n"); | ||
409 | return 0; | ||
410 | } | ||
411 | |||
412 | /* If no VGA responding in text mode, then we have some work to do... | ||
413 | */ | ||
414 | slot = -1; | ||
415 | while((slot = scanPCI(slot)) > -1) { /* find video card in use */ | ||
416 | unlockVideo(slot); /* enable I/O to card */ | ||
417 | VgaTextRegs = GenVgaTextRegs; | ||
418 | |||
419 | switch (PCIVendor(slot)) { | ||
420 | default: | ||
421 | break; | ||
422 | case(S3Vendor): | ||
423 | unlockS3(); | ||
424 | break; | ||
425 | |||
426 | case(CirrusVendor): | ||
427 | outw(0x3C4, 0x0612); /* unlock ext regs */ | ||
428 | outw(0x3C4, 0x0700); /* reset ext sequence mode */ | ||
429 | break; | ||
430 | |||
431 | case(ParadiseVendor): /* IBM Portable 850 */ | ||
432 | outw(0x3ce, 0x0f05); /* unlock pardise registers */ | ||
433 | outw(0x3c4, 0x0648); | ||
434 | outw(0x3d4, 0x2985); | ||
435 | outw(0x3d4, 0x34a6); | ||
436 | outb(0x3ce, 0x0b); /* disable linear addressing */ | ||
437 | outb(0x3cf, inb(0x3cf) & ~0x30); | ||
438 | outw(0x3c4, 0x1400); | ||
439 | outb(0x3ce, 0x0e); /* disable 256 color mode */ | ||
440 | outb(0x3cf, inb(0x3cf) & ~0x01); | ||
441 | outb(0xd00, 0xff); /* enable auto-centering */ | ||
442 | if (!(inb(0xd01) & 0x03)) { | ||
443 | outb(0x3d4, 0x33); | ||
444 | outb(0x3d5, inb(0x3d5) & ~0x90); | ||
445 | outb(0x3d4, 0x32); | ||
446 | outb(0x3d5, inb(0x3d5) | 0x04); | ||
447 | outw(0x3d4, 0x0250); | ||
448 | outw(0x3d4, 0x07ba); | ||
449 | outw(0x3d4, 0x0900); | ||
450 | outw(0x3d4, 0x15e7); | ||
451 | outw(0x3d4, 0x2a95); | ||
452 | } | ||
453 | outw(0x3d4, 0x34a0); | ||
454 | break; | ||
455 | |||
456 | #if 0 /* Untested - probably doesn't work */ | ||
457 | case(MatroxVendor): | ||
458 | case(DiamondVendor): | ||
459 | puts("VGA Chip Vendor ID: "); | ||
460 | puthex(PCIVendor(slot)); | ||
461 | puts("\n"); | ||
462 | mdelay(1000); | ||
463 | #endif | ||
464 | }; | ||
465 | |||
466 | outw(0x3C4, 0x0120); /* disable video */ | ||
467 | setTextRegs(VgaTextRegs); /* initial register setup */ | ||
468 | setTextCLUT(0); /* load color lookup table */ | ||
469 | loadFont(ISA_mem); /* load font */ | ||
470 | setTextRegs(VgaTextRegs); /* reload registers */ | ||
471 | outw(0x3C4, 0x0100); /* re-enable video */ | ||
472 | clearVideoMemory(); | ||
473 | |||
474 | if (PCIVendor(slot) == S3Vendor) { | ||
475 | outb(0x3c2, 0x63); /* MISC */ | ||
476 | } /* endif */ | ||
477 | |||
478 | #ifdef DEBUG | ||
479 | printslots(); | ||
480 | mdelay(5000); | ||
481 | #endif | ||
482 | |||
483 | mdelay(1000); /* give time for the video monitor to come up */ | ||
484 | } | ||
485 | return (1); /* 'CRT' I/O supported */ | ||
486 | } | ||
487 | |||
488 | /* | ||
489 | * Write to VGA Attribute registers. | ||
490 | */ | ||
491 | void | ||
492 | writeAttr(unsigned char index, unsigned char data, unsigned char videoOn) | ||
493 | { | ||
494 | unsigned char v; | ||
495 | v = inb(0x3da); /* reset attr. address toggle */ | ||
496 | if (videoOn) | ||
497 | outb(0x3c0, (index & 0x1F) | 0x20); | ||
498 | else | ||
499 | outb(0x3c0, (index & 0x1F)); | ||
500 | outb(0x3c0, data); | ||
501 | } | ||
502 | |||
503 | void | ||
504 | setTextRegs(struct VgaRegs *svp) | ||
505 | { | ||
506 | int i; | ||
507 | |||
508 | /* | ||
509 | * saved settings | ||
510 | */ | ||
511 | while( svp->io_port != ENDMK ) { | ||
512 | outb(svp->io_port, svp->io_index); | ||
513 | outb(svp->io_port+1, svp->io_value); | ||
514 | svp++; | ||
515 | } | ||
516 | |||
517 | outb(0x3c2, 0x67); /* MISC */ | ||
518 | outb(0x3c6, 0xff); /* MASK */ | ||
519 | |||
520 | for ( i = 0; i < 0x10; i++) | ||
521 | writeAttr(i, AC[i], 0); /* pallete */ | ||
522 | writeAttr(0x10, 0x0c, 0); /* text mode */ | ||
523 | writeAttr(0x11, 0x00, 0); /* overscan color (border) */ | ||
524 | writeAttr(0x12, 0x0f, 0); /* plane enable */ | ||
525 | writeAttr(0x13, 0x08, 0); /* pixel panning */ | ||
526 | writeAttr(0x14, 0x00, 1); /* color select; video on */ | ||
527 | } | ||
528 | |||
529 | void | ||
530 | setTextCLUT(int shift) | ||
531 | { | ||
532 | int i; | ||
533 | |||
534 | outb(0x3C6, 0xFF); | ||
535 | i = inb(0x3C7); | ||
536 | outb(0x3C8, 0); | ||
537 | i = inb(0x3C7); | ||
538 | |||
539 | for ( i = 0; i < 256; i++) { | ||
540 | outb(0x3C9, TextCLUT[i].r << shift); | ||
541 | outb(0x3C9, TextCLUT[i].g << shift); | ||
542 | outb(0x3C9, TextCLUT[i].b << shift); | ||
543 | } | ||
544 | } | ||
545 | |||
546 | void | ||
547 | loadFont(unsigned char *ISA_mem) | ||
548 | { | ||
549 | int i, j; | ||
550 | unsigned char *font_page = (unsigned char *) &ISA_mem[0xA0000]; | ||
551 | |||
552 | outb(0x3C2, 0x67); | ||
553 | /* | ||
554 | * Load font | ||
555 | */ | ||
556 | i = inb(0x3DA); /* Reset Attr toggle */ | ||
557 | |||
558 | outb(0x3C0,0x30); | ||
559 | outb(0x3C0, 0x01); /* graphics mode */ | ||
560 | |||
561 | outw(0x3C4, 0x0001); /* reset sequencer */ | ||
562 | outw(0x3C4, 0x0204); /* write to plane 2 */ | ||
563 | outw(0x3C4, 0x0406); /* enable plane graphics */ | ||
564 | outw(0x3C4, 0x0003); /* reset sequencer */ | ||
565 | outw(0x3CE, 0x0402); /* read plane 2 */ | ||
566 | outw(0x3CE, 0x0500); /* write mode 0, read mode 0 */ | ||
567 | outw(0x3CE, 0x0605); /* set graphics mode */ | ||
568 | |||
569 | for (i = 0; i < sizeof(font); i += 16) { | ||
570 | for (j = 0; j < 16; j++) { | ||
571 | __asm__ volatile("eieio"); | ||
572 | font_page[(2*i)+j] = font[i+j]; | ||
573 | } | ||
574 | } | ||
575 | } | ||
576 | |||
577 | static void | ||
578 | unlockS3(void) | ||
579 | { | ||
580 | int s3_device_id; | ||
581 | outw(0x3d4, 0x3848); | ||
582 | outw(0x3d4, 0x39a5); | ||
583 | outb(0x3d4, 0x2d); | ||
584 | s3_device_id = inb(0x3d5) << 8; | ||
585 | outb(0x3d4, 0x2e); | ||
586 | s3_device_id |= inb(0x3d5); | ||
587 | |||
588 | if (s3_device_id != 0x8812) { | ||
589 | /* From the S3 manual */ | ||
590 | outb(0x46E8, 0x10); /* Put into setup mode */ | ||
591 | outb(0x3C3, 0x10); | ||
592 | outb(0x102, 0x01); /* Enable registers */ | ||
593 | outb(0x46E8, 0x08); /* Enable video */ | ||
594 | outb(0x3C3, 0x08); | ||
595 | outb(0x4AE8, 0x00); | ||
596 | |||
597 | #if 0 | ||
598 | outb(0x42E8, 0x80); /* Reset graphics engine? */ | ||
599 | #endif | ||
600 | |||
601 | outb(0x3D4, 0x38); /* Unlock all registers */ | ||
602 | outb(0x3D5, 0x48); | ||
603 | outb(0x3D4, 0x39); | ||
604 | outb(0x3D5, 0xA5); | ||
605 | outb(0x3D4, 0x40); | ||
606 | outb(0x3D5, inb(0x3D5)|0x01); | ||
607 | outb(0x3D4, 0x33); | ||
608 | outb(0x3D5, inb(0x3D5)&~0x52); | ||
609 | outb(0x3D4, 0x35); | ||
610 | outb(0x3D5, inb(0x3D5)&~0x30); | ||
611 | outb(0x3D4, 0x3A); | ||
612 | outb(0x3D5, 0x00); | ||
613 | outb(0x3D4, 0x53); | ||
614 | outb(0x3D5, 0x00); | ||
615 | outb(0x3D4, 0x31); | ||
616 | outb(0x3D5, inb(0x3D5)&~0x4B); | ||
617 | outb(0x3D4, 0x58); | ||
618 | |||
619 | outb(0x3D5, 0); | ||
620 | |||
621 | outb(0x3D4, 0x54); | ||
622 | outb(0x3D5, 0x38); | ||
623 | outb(0x3D4, 0x60); | ||
624 | outb(0x3D5, 0x07); | ||
625 | outb(0x3D4, 0x61); | ||
626 | outb(0x3D5, 0x80); | ||
627 | outb(0x3D4, 0x62); | ||
628 | outb(0x3D5, 0xA1); | ||
629 | outb(0x3D4, 0x69); /* High order bits for cursor address */ | ||
630 | outb(0x3D5, 0); | ||
631 | |||
632 | outb(0x3D4, 0x32); | ||
633 | outb(0x3D5, inb(0x3D5)&~0x10); | ||
634 | } else { | ||
635 | outw(0x3c4, 0x0806); /* IBM Portable 860 */ | ||
636 | outw(0x3c4, 0x1041); | ||
637 | outw(0x3c4, 0x1128); | ||
638 | outw(0x3d4, 0x4000); | ||
639 | outw(0x3d4, 0x3100); | ||
640 | outw(0x3d4, 0x3a05); | ||
641 | outw(0x3d4, 0x6688); | ||
642 | outw(0x3d4, 0x5800); /* disable linear addressing */ | ||
643 | outw(0x3d4, 0x4500); /* disable H/W cursor */ | ||
644 | outw(0x3c4, 0x5410); /* enable auto-centering */ | ||
645 | outw(0x3c4, 0x561f); | ||
646 | outw(0x3c4, 0x1b80); /* lock DCLK selection */ | ||
647 | outw(0x3d4, 0x3900); /* lock S3 registers */ | ||
648 | outw(0x3d4, 0x3800); | ||
649 | } /* endif */ | ||
650 | } | ||
651 | |||
652 | /* | ||
653 | * cursor() sets an offset (0-1999) into the 80x25 text area. | ||
654 | */ | ||
655 | void | ||
656 | cursor(int x, int y) | ||
657 | { | ||
658 | int pos = (y*cols)+x; | ||
659 | outb(0x3D4, 14); | ||
660 | outb(0x3D5, pos >> 8); | ||
661 | outb(0x3D4, 15); | ||
662 | outb(0x3D5, pos); | ||
663 | } | ||
664 | |||
665 | void | ||
666 | clearVideoMemory(void) | ||
667 | { | ||
668 | int i, j; | ||
669 | for (i = 0; i < lines; i++) { | ||
670 | for (j = 0; j < cols; j++) { | ||
671 | vidmem[((i*cols)+j)*2] = 0x20; /* fill with space character */ | ||
672 | vidmem[((i*cols)+j)*2+1] = 0x07; /* set bg & fg attributes */ | ||
673 | } | ||
674 | } | ||
675 | } | ||
676 | |||
677 | /* ============ */ | ||
678 | |||
679 | |||
680 | #define NSLOTS 8 | ||
681 | #define NPCIREGS 5 | ||
682 | |||
683 | |||
684 | /* | ||
685 | should use devfunc number/indirect method to be totally safe on | ||
686 | all machines, this works for now on 3 slot Moto boxes | ||
687 | */ | ||
688 | |||
689 | struct PCI_ConfigInfo { | ||
690 | unsigned long * config_addr; | ||
691 | unsigned long regs[NPCIREGS]; | ||
692 | } PCI_slots [NSLOTS] = { | ||
693 | |||
694 | { (unsigned long *)0x80808000, {0xDEADBEEF,} }, /* onboard */ | ||
695 | { (unsigned long *)0x80800800, {0xDEADBEEF,} }, /* onboard */ | ||
696 | { (unsigned long *)0x80801000, {0xDEADBEEF,} }, /* onboard */ | ||
697 | { (unsigned long *)0x80802000, {0xDEADBEEF,} }, /* onboard */ | ||
698 | { (unsigned long *)0x80804000, {0xDEADBEEF,} }, /* onboard */ | ||
699 | { (unsigned long *)0x80810000, {0xDEADBEEF,} }, /* slot A/1 */ | ||
700 | { (unsigned long *)0x80820000, {0xDEADBEEF,} }, /* slot B/2 */ | ||
701 | { (unsigned long *)0x80840000, {0xDEADBEEF,} } /* slot C/3 */ | ||
702 | }; | ||
703 | |||
704 | |||
705 | |||
706 | /* | ||
707 | * The following code modifies the PCI Command register | ||
708 | * to enable memory and I/O accesses. | ||
709 | */ | ||
710 | void | ||
711 | unlockVideo(int slot) | ||
712 | { | ||
713 | volatile unsigned char * ppci; | ||
714 | |||
715 | ppci = (unsigned char * )PCI_slots[slot].config_addr; | ||
716 | ppci[4] = 0x0003; /* enable memory and I/O accesses */ | ||
717 | ppci[0x10] = 0x00000; /* turn off memory mapping */ | ||
718 | ppci[0x11] = 0x00000; /* mem_base = 0 */ | ||
719 | ppci[0x12] = 0x00000; | ||
720 | ppci[0x13] = 0x00000; | ||
721 | __asm__ volatile("eieio"); | ||
722 | |||
723 | outb(0x3d4, 0x11); | ||
724 | outb(0x3d5, 0x0e); /* unlock CR0-CR7 */ | ||
725 | } | ||
726 | |||
727 | long | ||
728 | SwapBytes(long lv) /* turn little endian into big indian long */ | ||
729 | { | ||
730 | long t; | ||
731 | t = (lv&0x000000FF) << 24; | ||
732 | t |= (lv&0x0000FF00) << 8; | ||
733 | t |= (lv&0x00FF0000) >> 8; | ||
734 | t |= (lv&0xFF000000) >> 24; | ||
735 | return(t); | ||
736 | } | ||
737 | |||
738 | |||
739 | #define DEVID 0 | ||
740 | #define CMD 1 | ||
741 | #define CLASS 2 | ||
742 | #define MEMBASE 4 | ||
743 | |||
744 | int | ||
745 | scanPCI(int start_slt) | ||
746 | { | ||
747 | int slt, r; | ||
748 | struct PCI_ConfigInfo *pslot; | ||
749 | int theSlot = -1; | ||
750 | int highVgaSlot = 0; | ||
751 | |||
752 | for ( slt = start_slt + 1; slt < NSLOTS; slt++) { | ||
753 | pslot = &PCI_slots[slt]; | ||
754 | for ( r = 0; r < NPCIREGS; r++) { | ||
755 | pslot->regs[r] = SwapBytes ( pslot->config_addr[r] ); | ||
756 | } | ||
757 | /* card in slot ? */ | ||
758 | if ( pslot->regs[DEVID] != 0xFFFFFFFF ) { | ||
759 | /* VGA ? */ | ||
760 | if ( ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x03000000) || | ||
761 | ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x00010000)) { | ||
762 | highVgaSlot = slt; | ||
763 | /* did firmware enable it ? */ | ||
764 | if ( (pslot->regs[CMD] & 0x03) ) { | ||
765 | theSlot = slt; | ||
766 | break; | ||
767 | } | ||
768 | } | ||
769 | } | ||
770 | } | ||
771 | |||
772 | return ( theSlot ); | ||
773 | } | ||
774 | |||
775 | /* return Vendor ID of card in the slot */ | ||
776 | static | ||
777 | int PCIVendor(int slotnum) { | ||
778 | struct PCI_ConfigInfo *pslot; | ||
779 | |||
780 | pslot = &PCI_slots[slotnum]; | ||
781 | |||
782 | return (pslot->regs[DEVID] & 0xFFFF); | ||
783 | } | ||
784 | |||
785 | #ifdef DEBUG | ||
786 | static | ||
787 | void printslots(void) | ||
788 | { | ||
789 | int i; | ||
790 | #if 0 | ||
791 | struct PCI_ConfigInfo *pslot; | ||
792 | #endif | ||
793 | for(i=0; i < NSLOTS; i++) { | ||
794 | #if 0 | ||
795 | pslot = &PCI_slots[i]; | ||
796 | printf("Slot: %d, Addr: %x, Vendor: %08x, Class: %08x\n", | ||
797 | i, pslot->config_addr, pslot->regs[0], pslot->regs[2]); | ||
798 | #else | ||
799 | puts("PCI Slot number: "); puthex(i); | ||
800 | puts(" Vendor ID: "); | ||
801 | puthex(PCIVendor(i)); puts("\n"); | ||
802 | #endif | ||
803 | } | ||
804 | } | ||
805 | #endif /* DEBUG */ | ||
diff --git a/arch/ppc/boot/of1275/Makefile b/arch/ppc/boot/of1275/Makefile new file mode 100644 index 000000000000..02e6f235d7cb --- /dev/null +++ b/arch/ppc/boot/of1275/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | # | ||
2 | # Makefile of1275 stuff | ||
3 | # | ||
4 | |||
5 | lib-y := claim.o enter.o exit.o finddevice.o getprop.o ofinit.o \ | ||
6 | ofstdio.o read.o release.o write.o map.o | ||
diff --git a/arch/ppc/boot/of1275/claim.c b/arch/ppc/boot/of1275/claim.c new file mode 100644 index 000000000000..e060292ae2a7 --- /dev/null +++ b/arch/ppc/boot/of1275/claim.c | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * Copyright (C) Leigh Brown 2002. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include "of1275.h" | ||
12 | |||
13 | void * | ||
14 | claim(unsigned int virt, unsigned int size, unsigned int align) | ||
15 | { | ||
16 | struct prom_args { | ||
17 | char *service; | ||
18 | int nargs; | ||
19 | int nret; | ||
20 | unsigned int virt; | ||
21 | unsigned int size; | ||
22 | unsigned int align; | ||
23 | void *ret; | ||
24 | } args; | ||
25 | |||
26 | args.service = "claim"; | ||
27 | args.nargs = 3; | ||
28 | args.nret = 1; | ||
29 | args.virt = virt; | ||
30 | args.size = size; | ||
31 | args.align = align; | ||
32 | (*of_prom_entry)(&args); | ||
33 | return args.ret; | ||
34 | } | ||
diff --git a/arch/ppc/boot/of1275/enter.c b/arch/ppc/boot/of1275/enter.c new file mode 100644 index 000000000000..abe87a8fe2db --- /dev/null +++ b/arch/ppc/boot/of1275/enter.c | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * Copyright (C) Leigh Brown 2002. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include "of1275.h" | ||
12 | |||
13 | void | ||
14 | enter(void) | ||
15 | { | ||
16 | struct prom_args { | ||
17 | char *service; | ||
18 | } args; | ||
19 | |||
20 | args.service = "enter"; | ||
21 | (*of_prom_entry)(&args); | ||
22 | } | ||
diff --git a/arch/ppc/boot/of1275/exit.c b/arch/ppc/boot/of1275/exit.c new file mode 100644 index 000000000000..b9f89b6a8b45 --- /dev/null +++ b/arch/ppc/boot/of1275/exit.c | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * Copyright (C) Leigh Brown 2002. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include "of1275.h" | ||
12 | |||
13 | void | ||
14 | exit(void) | ||
15 | { | ||
16 | struct prom_args { | ||
17 | char *service; | ||
18 | } args; | ||
19 | |||
20 | for (;;) { | ||
21 | args.service = "exit"; | ||
22 | (*of_prom_entry)(&args); | ||
23 | } | ||
24 | } | ||
diff --git a/arch/ppc/boot/of1275/finddevice.c b/arch/ppc/boot/of1275/finddevice.c new file mode 100644 index 000000000000..2c0f7cbb793e --- /dev/null +++ b/arch/ppc/boot/of1275/finddevice.c | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * Copyright (C) Leigh Brown 2002. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include "of1275.h" | ||
12 | |||
13 | phandle | ||
14 | finddevice(const char *name) | ||
15 | { | ||
16 | struct prom_args { | ||
17 | char *service; | ||
18 | int nargs; | ||
19 | int nret; | ||
20 | const char *devspec; | ||
21 | phandle device; | ||
22 | } args; | ||
23 | |||
24 | args.service = "finddevice"; | ||
25 | args.nargs = 1; | ||
26 | args.nret = 1; | ||
27 | args.devspec = name; | ||
28 | args.device = OF_INVALID_HANDLE; | ||
29 | (*of_prom_entry)(&args); | ||
30 | return args.device; | ||
31 | } | ||
diff --git a/arch/ppc/boot/of1275/getprop.c b/arch/ppc/boot/of1275/getprop.c new file mode 100644 index 000000000000..0cf75f035e4e --- /dev/null +++ b/arch/ppc/boot/of1275/getprop.c | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * Copyright (C) Leigh Brown 2002. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include "of1275.h" | ||
12 | |||
13 | int | ||
14 | getprop(phandle node, const char *name, void *buf, int buflen) | ||
15 | { | ||
16 | struct prom_args { | ||
17 | char *service; | ||
18 | int nargs; | ||
19 | int nret; | ||
20 | phandle node; | ||
21 | const char *name; | ||
22 | void *buf; | ||
23 | int buflen; | ||
24 | int size; | ||
25 | } args; | ||
26 | |||
27 | args.service = "getprop"; | ||
28 | args.nargs = 4; | ||
29 | args.nret = 1; | ||
30 | args.node = node; | ||
31 | args.name = name; | ||
32 | args.buf = buf; | ||
33 | args.buflen = buflen; | ||
34 | args.size = -1; | ||
35 | (*of_prom_entry)(&args); | ||
36 | return args.size; | ||
37 | } | ||
diff --git a/arch/ppc/boot/of1275/map.c b/arch/ppc/boot/of1275/map.c new file mode 100644 index 000000000000..443256c6f6d6 --- /dev/null +++ b/arch/ppc/boot/of1275/map.c | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * Copyright (C) Leigh Brown 2002. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include "of1275.h" | ||
12 | #include "nonstdio.h" | ||
13 | |||
14 | extern ihandle of_prom_mmu; | ||
15 | |||
16 | int | ||
17 | map(unsigned int phys, unsigned int virt, unsigned int size) | ||
18 | { | ||
19 | struct prom_args { | ||
20 | char *service; | ||
21 | int nargs; | ||
22 | int nret; | ||
23 | char *method; | ||
24 | ihandle mmu_ihandle; | ||
25 | int misc; | ||
26 | unsigned int size; | ||
27 | unsigned int virt; | ||
28 | unsigned int phys; | ||
29 | int ret0; | ||
30 | } args; | ||
31 | |||
32 | if (of_prom_mmu == 0) { | ||
33 | printf("map() called, no MMU found\n"); | ||
34 | return -1; | ||
35 | } | ||
36 | args.service = "call-method"; | ||
37 | args.nargs = 6; | ||
38 | args.nret = 1; | ||
39 | args.method = "map"; | ||
40 | args.mmu_ihandle = of_prom_mmu; | ||
41 | args.misc = 0; | ||
42 | args.phys = phys; | ||
43 | args.virt = virt; | ||
44 | args.size = size; | ||
45 | (*of_prom_entry)(&args); | ||
46 | |||
47 | return (int)args.ret0; | ||
48 | } | ||
diff --git a/arch/ppc/boot/of1275/ofinit.c b/arch/ppc/boot/of1275/ofinit.c new file mode 100644 index 000000000000..0ee8af7639e9 --- /dev/null +++ b/arch/ppc/boot/of1275/ofinit.c | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * Copyright (C) Leigh Brown 2002. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include "of1275.h" | ||
12 | |||
13 | prom_entry of_prom_entry; | ||
14 | ihandle of_prom_mmu; | ||
15 | |||
16 | void | ||
17 | ofinit(prom_entry prom_ptr) | ||
18 | { | ||
19 | phandle chosen; | ||
20 | |||
21 | of_prom_entry = prom_ptr; | ||
22 | |||
23 | if ((chosen = finddevice("/chosen")) == OF_INVALID_HANDLE) | ||
24 | return; | ||
25 | if (getprop(chosen, "mmu", &of_prom_mmu, sizeof(ihandle)) != 4) | ||
26 | return; | ||
27 | } | ||
diff --git a/arch/ppc/boot/of1275/ofstdio.c b/arch/ppc/boot/of1275/ofstdio.c new file mode 100644 index 000000000000..10abbe32b31f --- /dev/null +++ b/arch/ppc/boot/of1275/ofstdio.c | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * Copyright (C) Leigh Brown 2002. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include "of1275.h" | ||
12 | |||
13 | int | ||
14 | ofstdio(ihandle *stdin, ihandle *stdout, ihandle *stderr) | ||
15 | { | ||
16 | ihandle in, out; | ||
17 | phandle chosen; | ||
18 | |||
19 | if ((chosen = finddevice("/chosen")) == OF_INVALID_HANDLE) | ||
20 | goto err; | ||
21 | if (getprop(chosen, "stdout", &out, sizeof(out)) != 4) | ||
22 | goto err; | ||
23 | if (getprop(chosen, "stdin", &in, sizeof(in)) != 4) | ||
24 | goto err; | ||
25 | |||
26 | *stdin = in; | ||
27 | *stdout = out; | ||
28 | *stderr = out; | ||
29 | return 0; | ||
30 | err: | ||
31 | return -1; | ||
32 | } | ||
diff --git a/arch/ppc/boot/of1275/read.c b/arch/ppc/boot/of1275/read.c new file mode 100644 index 000000000000..122813649fce --- /dev/null +++ b/arch/ppc/boot/of1275/read.c | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * Copyright (C) Leigh Brown 2002. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include "of1275.h" | ||
12 | |||
13 | int | ||
14 | read(ihandle instance, void *buf, int buflen) | ||
15 | { | ||
16 | struct prom_args { | ||
17 | char *service; | ||
18 | int nargs; | ||
19 | int nret; | ||
20 | ihandle instance; | ||
21 | void *buf; | ||
22 | int buflen; | ||
23 | int actual; | ||
24 | } args; | ||
25 | |||
26 | args.service = "read"; | ||
27 | args.nargs = 3; | ||
28 | args.nret = 1; | ||
29 | args.instance = instance; | ||
30 | args.buf = buf; | ||
31 | args.buflen = buflen; | ||
32 | args.actual = -1; | ||
33 | (*of_prom_entry)(&args); | ||
34 | return args.actual; | ||
35 | } | ||
diff --git a/arch/ppc/boot/of1275/release.c b/arch/ppc/boot/of1275/release.c new file mode 100644 index 000000000000..28032d37145d --- /dev/null +++ b/arch/ppc/boot/of1275/release.c | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * Copyright (C) Leigh Brown 2002. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include "of1275.h" | ||
12 | |||
13 | void | ||
14 | release(void *virt, unsigned int size) | ||
15 | { | ||
16 | struct prom_args { | ||
17 | char *service; | ||
18 | int nargs; | ||
19 | int nret; | ||
20 | void *virt; | ||
21 | unsigned int size; | ||
22 | } args; | ||
23 | |||
24 | args.service = "release"; | ||
25 | args.nargs = 2; | ||
26 | args.nret = 0; | ||
27 | args.virt = virt; | ||
28 | args.size = size; | ||
29 | (*of_prom_entry)(&args); | ||
30 | } | ||
diff --git a/arch/ppc/boot/of1275/write.c b/arch/ppc/boot/of1275/write.c new file mode 100644 index 000000000000..7361b9b2fca5 --- /dev/null +++ b/arch/ppc/boot/of1275/write.c | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * Copyright (C) Leigh Brown 2002. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include "of1275.h" | ||
12 | |||
13 | int | ||
14 | write(ihandle instance, void *buf, int buflen) | ||
15 | { | ||
16 | struct prom_args { | ||
17 | char *service; | ||
18 | int nargs; | ||
19 | int nret; | ||
20 | ihandle instance; | ||
21 | void *buf; | ||
22 | int buflen; | ||
23 | int actual; | ||
24 | } args; | ||
25 | |||
26 | args.service = "write"; | ||
27 | args.nargs = 3; | ||
28 | args.nret = 1; | ||
29 | args.instance = instance; | ||
30 | args.buf = buf; | ||
31 | args.buflen = buflen; | ||
32 | args.actual = -1; | ||
33 | (*of_prom_entry)(&args); | ||
34 | return args.actual; | ||
35 | } | ||
diff --git a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile new file mode 100644 index 000000000000..4eacbd8c772a --- /dev/null +++ b/arch/ppc/boot/openfirmware/Makefile | |||
@@ -0,0 +1,188 @@ | |||
1 | # Makefile for making bootable images on various OpenFirmware machines. | ||
2 | # | ||
3 | # Paul Mackerras January 1997 | ||
4 | # XCOFF bootable images for PowerMacs | ||
5 | # Geert Uytterhoeven September 1997 | ||
6 | # ELF bootable iamges for CHRP machines. | ||
7 | # Tom Rini January 2001 | ||
8 | # Cleaned up, moved into arch/ppc/boot/pmac | ||
9 | # Tom Rini July/August 2002 | ||
10 | # Merged 'chrp' and 'pmac' into 'openfirmware', and cleaned up the | ||
11 | # rules. | ||
12 | |||
13 | zImage.initrd znetboot.initrd: del-ramdisk-sec := -R .ramdisk | ||
14 | zImage.initrd znetboot.initrd: initrd := .initrd | ||
15 | |||
16 | |||
17 | boot := arch/ppc/boot | ||
18 | common := $(boot)/common | ||
19 | utils := $(boot)/utils | ||
20 | bootlib := $(boot)/lib | ||
21 | of1275 := $(boot)/of1275 | ||
22 | images := $(boot)/images | ||
23 | |||
24 | OBJCOPY_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment | ||
25 | COFF_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00500000 \ | ||
26 | -Bstatic | ||
27 | CHRP_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00800000 | ||
28 | NEWWORLD_LD_ARGS:= -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x01000000 | ||
29 | |||
30 | COMMONOBJS := start.o misc.o common.o | ||
31 | COFFOBJS := coffcrt0.o $(COMMONOBJS) coffmain.o | ||
32 | CHRPOBJS := crt0.o $(COMMONOBJS) chrpmain.o | ||
33 | NEWWORLDOBJS := crt0.o $(COMMONOBJS) newworldmain.o | ||
34 | |||
35 | targets := $(COFFOBJS) $(CHRPOBJS) $(NEWWORLDOBJS) dummy.o | ||
36 | COFFOBJS := $(addprefix $(obj)/, $(COFFOBJS)) | ||
37 | CHRPOBJS := $(addprefix $(obj)/, $(CHRPOBJS)) | ||
38 | NEWWORLDOBJS := $(addprefix $(obj)/, $(NEWWORLDOBJS)) | ||
39 | |||
40 | LIBS := lib/lib.a $(bootlib)/lib.a $(of1275)/lib.a $(common)/lib.a | ||
41 | |||
42 | HACKCOFF := $(utils)/hack-coff | ||
43 | |||
44 | ifdef CONFIG_SMP | ||
45 | END := .smp | ||
46 | endif | ||
47 | ifdef CONFIG_PPC64BRIDGE | ||
48 | END += .64 | ||
49 | endif | ||
50 | |||
51 | |||
52 | $(images)/ramdisk.image.gz: | ||
53 | @echo ' MISSING $@' | ||
54 | @echo ' RAM disk image must be provided separately' | ||
55 | @/bin/false | ||
56 | |||
57 | objcpxmon-$(CONFIG_XMON) := --add-section=.sysmap=System.map \ | ||
58 | --set-section-flags=.sysmap=contents,alloc,load,readonly,data | ||
59 | quiet_cmd_genimage = GEN $@ | ||
60 | cmd_genimage = $(OBJCOPY) -R .comment \ | ||
61 | --add-section=.image=$(images)/vmlinux.gz \ | ||
62 | --set-section-flags=.image=contents,alloc,load,readonly,data \ | ||
63 | $(objcpxmon-y) $< $@ | ||
64 | |||
65 | targets += image.o | ||
66 | $(obj)/image.o: $(obj)/dummy.o $(images)/vmlinux.gz FORCE | ||
67 | $(call if_changed,genimage) | ||
68 | |||
69 | # Place the ramdisk in the initrd image. | ||
70 | quiet_cmd_genimage-initrd = GEN $@ | ||
71 | cmd_genimage-initrd = $(OBJCOPY) $< $@ \ | ||
72 | --add-section=.ramdisk=$(images)/ramdisk.image.gz \ | ||
73 | --set-section-flags=.ramdisk=contents,alloc,load,readonly,data | ||
74 | targets += image.initrd.o | ||
75 | $(obj)/image.initrd.o: $(obj)/image.o $(images)/ramdisk.image.gz FORCE | ||
76 | $(call if_changed,genimage-initrd) | ||
77 | |||
78 | # Create the note section for New-World PowerMacs. | ||
79 | quiet_cmd_mknote = MKNOTE $@ | ||
80 | cmd_mknote = $(utils)/mknote > $@ | ||
81 | targets += note | ||
82 | $(obj)/note: $(utils)/mknote FORCE | ||
83 | $(call if_changed,mknote) | ||
84 | |||
85 | |||
86 | $(obj)/coffcrt0.o: EXTRA_AFLAGS := -traditional -DXCOFF | ||
87 | $(obj)/crt0.o: EXTRA_AFLAGS := -traditional | ||
88 | targets += coffcrt0.o crt0.o | ||
89 | $(obj)/coffcrt0.o $(obj)/crt0.o: $(common)/crt0.S FORCE | ||
90 | $(call if_changed_dep,as_o_S) | ||
91 | |||
92 | quiet_cmd_gencoffb = COFF $@ | ||
93 | cmd_gencoffb = $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) $< $(LIBS) && \ | ||
94 | $(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec) | ||
95 | targets += coffboot | ||
96 | $(obj)/coffboot: $(obj)/image.o $(COFFOBJS) $(LIBS) $(srctree)/$(boot)/ld.script FORCE | ||
97 | $(call if_changed,gencoffb) | ||
98 | targets += coffboot.initrd | ||
99 | $(obj)/coffboot.initrd: $(obj)/image.initrd.o $(COFFOBJS) $(LIBS) \ | ||
100 | $(srctree)/$(boot)/ld.script FORCE | ||
101 | $(call if_changed,gencoffb) | ||
102 | |||
103 | |||
104 | quiet_cmd_gen-coff = COFF $@ | ||
105 | cmd_gen-coff = $(OBJCOPY) $(OBJCOPY_ARGS) $< $@ && \ | ||
106 | $(HACKCOFF) $@ && \ | ||
107 | ln -sf $(notdir $@) $(images)/zImage$(initrd).pmac | ||
108 | |||
109 | $(images)/vmlinux.coff: $(obj)/coffboot | ||
110 | $(call cmd,gen-coff) | ||
111 | |||
112 | $(images)/vmlinux.initrd.coff: $(obj)/coffboot.initrd | ||
113 | $(call cmd,gen-coff) | ||
114 | |||
115 | quiet_cmd_gen-elf-pmac = ELF $@ | ||
116 | cmd_gen-elf-pmac = $(LD) $(NEWWORLD_LD_ARGS) -o $@ \ | ||
117 | $(NEWWORLDOBJS) $(LIBS) $< && \ | ||
118 | $(OBJCOPY) $@ $@ --add-section=.note=$(obj)/note \ | ||
119 | -R .comment $(del-ramdisk-sec) | ||
120 | |||
121 | $(images)/vmlinux.elf-pmac: $(obj)/image.o $(NEWWORLDOBJS) $(LIBS) \ | ||
122 | $(obj)/note $(srctree)/$(boot)/ld.script | ||
123 | $(call cmd,gen-elf-pmac) | ||
124 | $(images)/vmlinux.initrd.elf-pmac: $(obj)/image.initrd.o $(NEWWORLDOBJS) \ | ||
125 | $(LIBS) $(obj)/note \ | ||
126 | $(srctree)/$(boot)/ld.script | ||
127 | $(call cmd,gen-elf-pmac) | ||
128 | |||
129 | quiet_cmd_gen-chrp = CHRP $@ | ||
130 | cmd_gen-chrp = $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) $< $(LIBS) && \ | ||
131 | $(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec) | ||
132 | |||
133 | $(images)/zImage.chrp: $(obj)/image.o $(CHRPOBJS) $(LIBS) \ | ||
134 | $(srctree)/$(boot)/ld.script | ||
135 | $(call cmd,gen-chrp) | ||
136 | $(images)/zImage.initrd.chrp: $(obj)/image.initrd.o $(CHRPOBJS) $(LIBS) \ | ||
137 | $(srctree)/$(boot)/ld.script | ||
138 | $(call cmd,gen-chrp) | ||
139 | |||
140 | quiet_cmd_addnote = ADDNOTE $@ | ||
141 | cmd_addnote = cat $< > $@ && $(utils)/addnote $@ | ||
142 | $(images)/zImage.chrp-rs6k $(images)/zImage.initrd.chrp-rs6k: \ | ||
143 | %-rs6k: % | ||
144 | $(call cmd,addnote) | ||
145 | |||
146 | quiet_cmd_gen-miboot = GEN $@ | ||
147 | cmd_gen-miboot = $(OBJCOPY) $(OBJCOPY_ARGS) \ | ||
148 | --add-section=$1=$(word 2, $^) $< $@ | ||
149 | $(images)/miboot.image: $(obj)/dummy.o $(images)/vmlinux.gz | ||
150 | $(call cmd,gen-miboot,image) | ||
151 | |||
152 | $(images)/miboot.initrd.image: $(images)/miboot.image $(images)/ramdisk.image.gz | ||
153 | $(call cmd,gen-miboot,initrd) | ||
154 | |||
155 | # The targets used on the make command-line | ||
156 | |||
157 | .PHONY: zImage zImage.initrd | ||
158 | zImage: $(images)/vmlinux.coff \ | ||
159 | $(images)/vmlinux.elf-pmac \ | ||
160 | $(images)/zImage.chrp \ | ||
161 | $(images)/zImage.chrp-rs6k \ | ||
162 | $(images)/miboot.image | ||
163 | @echo ' kernel: $@ is ready ($<)' | ||
164 | zImage.initrd: $(images)/vmlinux.initrd.coff \ | ||
165 | $(images)/vmlinux.initrd.elf-pmac \ | ||
166 | $(images)/zImage.initrd.chrp \ | ||
167 | $(images)/zImage.initrd.chrp-rs6k \ | ||
168 | $(images)/miboot.initrd.image | ||
169 | @echo ' kernel: $@ is ready ($<)' | ||
170 | |||
171 | TFTPIMAGE := /tftpboot/zImage | ||
172 | |||
173 | .PHONY: znetboot znetboot.initrd | ||
174 | znetboot: $(images)/vmlinux.coff \ | ||
175 | $(images)/vmlinux.elf-pmac \ | ||
176 | $(images)/zImage.chrp | ||
177 | cp $(images)/vmlinux.coff $(TFTPIMAGE).pmac$(END) | ||
178 | cp $(images)/vmlinux.elf-pmac $(TFTPIMAGE).pmac$(END).elf | ||
179 | cp $(images)/zImage.chrp $(TFTPIMAGE).chrp$(END) | ||
180 | @echo ' kernel: $@ is ready ($<)' | ||
181 | znetboot.initrd:$(images)/vmlinux.initrd.coff \ | ||
182 | $(images)/vmlinux.initrd.elf-pmac \ | ||
183 | $(images)/zImage.initrd.chrp | ||
184 | cp $(images)/vmlinux.initrd.coff $(TFTPIMAGE).pmac$(END) | ||
185 | cp $(images)/vmlinux.initrd.elf-pmac $(TFTPIMAGE).pmac$(END).elf | ||
186 | cp $(images)/zImage.initrd.chrp $(TFTPIMAGE).chrp$(END) | ||
187 | @echo ' kernel: $@ is ready ($<)' | ||
188 | |||
diff --git a/arch/ppc/boot/openfirmware/chrpmain.c b/arch/ppc/boot/openfirmware/chrpmain.c new file mode 100644 index 000000000000..6fb4f738728c --- /dev/null +++ b/arch/ppc/boot/openfirmware/chrpmain.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | #include <linux/string.h> | ||
10 | #include "nonstdio.h" | ||
11 | #include "of1275.h" | ||
12 | #include <asm/processor.h> | ||
13 | #include <asm/page.h> | ||
14 | |||
15 | /* Passed from the linker */ | ||
16 | extern char __image_begin, __image_end; | ||
17 | extern char __ramdisk_begin, __ramdisk_end; | ||
18 | extern char _start, _end; | ||
19 | |||
20 | extern unsigned int heap_max; | ||
21 | extern void flush_cache(void *, unsigned long); | ||
22 | extern void gunzip(void *, int, unsigned char *, int *); | ||
23 | extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, | ||
24 | unsigned int progend); | ||
25 | |||
26 | char *avail_ram; | ||
27 | char *begin_avail, *end_avail; | ||
28 | char *avail_high; | ||
29 | |||
30 | #define RAM_START 0x00000000 | ||
31 | #define RAM_END (64<<20) | ||
32 | |||
33 | #define BOOT_START ((unsigned long)_start) | ||
34 | #define BOOT_END ((unsigned long)(_end + 0xFFF) & ~0xFFF) | ||
35 | |||
36 | #define RAM_FREE ((unsigned long)(_end+0x1000)&~0xFFF) | ||
37 | #define PROG_START 0x00010000 | ||
38 | #define PROG_SIZE 0x007f0000 /* 8MB */ | ||
39 | |||
40 | #define SCRATCH_SIZE (128 << 10) | ||
41 | |||
42 | static char scratch[SCRATCH_SIZE]; /* 1MB of scratch space for gunzip */ | ||
43 | |||
44 | typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int); | ||
45 | |||
46 | void | ||
47 | boot(int a1, int a2, void *prom) | ||
48 | { | ||
49 | unsigned sa, len; | ||
50 | void *dst; | ||
51 | unsigned char *im; | ||
52 | unsigned int initrd_size, initrd_start; | ||
53 | |||
54 | printf("chrpboot starting: loaded at 0x%p\n\r", &_start); | ||
55 | |||
56 | initrd_size = &__ramdisk_end - &__ramdisk_begin; | ||
57 | if (initrd_size) { | ||
58 | initrd_start = (RAM_END - initrd_size) & ~0xFFF; | ||
59 | a1 = initrd_start; | ||
60 | a2 = initrd_size; | ||
61 | claim(initrd_start, RAM_END - initrd_start, 0); | ||
62 | printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r", | ||
63 | initrd_start, &__ramdisk_begin, initrd_size); | ||
64 | memcpy((char *)initrd_start, &__ramdisk_begin, initrd_size); | ||
65 | } else { | ||
66 | initrd_start = 0; | ||
67 | initrd_size = 0; | ||
68 | a2 = 0xdeadbeef; | ||
69 | } | ||
70 | |||
71 | im = &__image_begin; | ||
72 | len = &__image_end - &__image_begin; | ||
73 | /* claim 4MB starting at PROG_START */ | ||
74 | claim(PROG_START, PROG_SIZE - PROG_START, 0); | ||
75 | dst = (void *) PROG_START; | ||
76 | if (im[0] == 0x1f && im[1] == 0x8b) { | ||
77 | avail_ram = scratch; | ||
78 | begin_avail = avail_high = avail_ram; | ||
79 | end_avail = scratch + sizeof(scratch); | ||
80 | printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len); | ||
81 | gunzip(dst, 0x400000, im, &len); | ||
82 | printf("done %u bytes\n\r", len); | ||
83 | printf("%u bytes of heap consumed, max in use %u\n\r", | ||
84 | avail_high - begin_avail, heap_max); | ||
85 | } else { | ||
86 | memmove(dst, im, len); | ||
87 | } | ||
88 | |||
89 | flush_cache(dst, len); | ||
90 | make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_chrp, | ||
91 | (PROG_START + PROG_SIZE)); | ||
92 | |||
93 | sa = PROG_START; | ||
94 | printf("start address = 0x%x\n\r", sa); | ||
95 | |||
96 | (*(kernel_start_t)sa)(a1, a2, prom, initrd_start, initrd_size); | ||
97 | |||
98 | printf("returned?\n\r"); | ||
99 | |||
100 | pause(); | ||
101 | } | ||
diff --git a/arch/ppc/boot/openfirmware/coffmain.c b/arch/ppc/boot/openfirmware/coffmain.c new file mode 100644 index 000000000000..04ba9d57e110 --- /dev/null +++ b/arch/ppc/boot/openfirmware/coffmain.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | #include <linux/string.h> | ||
10 | #include <asm/processor.h> | ||
11 | #include <asm/page.h> | ||
12 | |||
13 | #include "nonstdio.h" | ||
14 | #include "of1275.h" | ||
15 | |||
16 | /* Passed from the linker */ | ||
17 | extern char __image_begin, __image_end; | ||
18 | extern char __ramdisk_begin[], __ramdisk_end; | ||
19 | extern char _start, _end; | ||
20 | |||
21 | extern char image_data[], initrd_data[]; | ||
22 | extern int initrd_len, image_len; | ||
23 | extern unsigned int heap_max; | ||
24 | extern void flush_cache(void *start, unsigned int len); | ||
25 | extern void gunzip(void *, int, unsigned char *, int *); | ||
26 | extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, | ||
27 | unsigned int progend); | ||
28 | extern void setup_bats(unsigned long start); | ||
29 | |||
30 | char *avail_ram; | ||
31 | char *begin_avail, *end_avail; | ||
32 | char *avail_high; | ||
33 | |||
34 | #define SCRATCH_SIZE (128 << 10) | ||
35 | |||
36 | static char heap[SCRATCH_SIZE]; | ||
37 | |||
38 | static unsigned long ram_start = 0; | ||
39 | static unsigned long ram_end = 0x1000000; | ||
40 | |||
41 | static unsigned long prog_start = 0x900000; | ||
42 | static unsigned long prog_size = 0x700000; | ||
43 | |||
44 | typedef void (*kernel_start_t)(int, int, void *); | ||
45 | |||
46 | void boot(int a1, int a2, void *prom) | ||
47 | { | ||
48 | unsigned sa, len; | ||
49 | void *dst; | ||
50 | unsigned char *im; | ||
51 | unsigned initrd_start, initrd_size; | ||
52 | |||
53 | printf("coffboot starting: loaded at 0x%p\n", &_start); | ||
54 | setup_bats(ram_start); | ||
55 | |||
56 | initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin); | ||
57 | if (initrd_size) { | ||
58 | initrd_start = (ram_end - initrd_size) & ~0xFFF; | ||
59 | a1 = initrd_start; | ||
60 | a2 = initrd_size; | ||
61 | claim(initrd_start, ram_end - initrd_start, 0); | ||
62 | printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r", | ||
63 | initrd_start, (char *)(&__ramdisk_begin), initrd_size); | ||
64 | memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size); | ||
65 | prog_size = initrd_start - prog_start; | ||
66 | } else | ||
67 | a2 = 0xdeadbeef; | ||
68 | |||
69 | im = (char *)(&__image_begin); | ||
70 | len = (char *)(&__image_end) - (char *)(&__image_begin); | ||
71 | /* claim 4MB starting at PROG_START */ | ||
72 | claim(prog_start, prog_size, 0); | ||
73 | map(prog_start, prog_start, prog_size); | ||
74 | dst = (void *) prog_start; | ||
75 | if (im[0] == 0x1f && im[1] == 0x8b) { | ||
76 | /* set up scratch space */ | ||
77 | begin_avail = avail_high = avail_ram = heap; | ||
78 | end_avail = heap + sizeof(heap); | ||
79 | printf("heap at 0x%p\n", avail_ram); | ||
80 | printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len); | ||
81 | gunzip(dst, prog_size, im, &len); | ||
82 | printf("done %u bytes\n", len); | ||
83 | printf("%u bytes of heap consumed, max in use %u\n", | ||
84 | avail_high - begin_avail, heap_max); | ||
85 | } else { | ||
86 | memmove(dst, im, len); | ||
87 | } | ||
88 | |||
89 | flush_cache(dst, len); | ||
90 | make_bi_recs(((unsigned long) dst + len), "coffboot", _MACH_Pmac, | ||
91 | (prog_start + prog_size)); | ||
92 | |||
93 | sa = (unsigned long)prog_start; | ||
94 | printf("start address = 0x%x\n", sa); | ||
95 | |||
96 | (*(kernel_start_t)sa)(a1, a2, prom); | ||
97 | |||
98 | printf("returned?\n"); | ||
99 | |||
100 | pause(); | ||
101 | } | ||
diff --git a/arch/ppc/boot/openfirmware/common.c b/arch/ppc/boot/openfirmware/common.c new file mode 100644 index 000000000000..9e6952781f1f --- /dev/null +++ b/arch/ppc/boot/openfirmware/common.c | |||
@@ -0,0 +1,162 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include "nonstdio.h" | ||
11 | #include "of1275.h" | ||
12 | #include <linux/string.h> | ||
13 | #include <linux/zlib.h> | ||
14 | #include <asm/bootinfo.h> | ||
15 | #include <asm/page.h> | ||
16 | |||
17 | /* Information from the linker */ | ||
18 | extern char __sysmap_begin, __sysmap_end; | ||
19 | |||
20 | extern int strcmp(const char *s1, const char *s2); | ||
21 | extern char *avail_ram, *avail_high; | ||
22 | extern char *end_avail; | ||
23 | |||
24 | unsigned int heap_use, heap_max; | ||
25 | |||
26 | struct memchunk { | ||
27 | unsigned int size; | ||
28 | struct memchunk *next; | ||
29 | }; | ||
30 | |||
31 | static struct memchunk *freechunks; | ||
32 | |||
33 | static void *zalloc(unsigned size) | ||
34 | { | ||
35 | void *p; | ||
36 | struct memchunk **mpp, *mp; | ||
37 | |||
38 | size = (size + 7) & -8; | ||
39 | heap_use += size; | ||
40 | if (heap_use > heap_max) | ||
41 | heap_max = heap_use; | ||
42 | for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) { | ||
43 | if (mp->size == size) { | ||
44 | *mpp = mp->next; | ||
45 | return mp; | ||
46 | } | ||
47 | } | ||
48 | p = avail_ram; | ||
49 | avail_ram += size; | ||
50 | if (avail_ram > avail_high) | ||
51 | avail_high = avail_ram; | ||
52 | if (avail_ram > end_avail) { | ||
53 | printf("oops... out of memory\n\r"); | ||
54 | pause(); | ||
55 | } | ||
56 | return p; | ||
57 | } | ||
58 | |||
59 | #define HEAD_CRC 2 | ||
60 | #define EXTRA_FIELD 4 | ||
61 | #define ORIG_NAME 8 | ||
62 | #define COMMENT 0x10 | ||
63 | #define RESERVED 0xe0 | ||
64 | |||
65 | void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) | ||
66 | { | ||
67 | z_stream s; | ||
68 | int r, i, flags; | ||
69 | |||
70 | /* skip header */ | ||
71 | i = 10; | ||
72 | flags = src[3]; | ||
73 | if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) { | ||
74 | printf("bad gzipped data\n\r"); | ||
75 | exit(); | ||
76 | } | ||
77 | if ((flags & EXTRA_FIELD) != 0) | ||
78 | i = 12 + src[10] + (src[11] << 8); | ||
79 | if ((flags & ORIG_NAME) != 0) | ||
80 | while (src[i++] != 0) | ||
81 | ; | ||
82 | if ((flags & COMMENT) != 0) | ||
83 | while (src[i++] != 0) | ||
84 | ; | ||
85 | if ((flags & HEAD_CRC) != 0) | ||
86 | i += 2; | ||
87 | if (i >= *lenp) { | ||
88 | printf("gunzip: ran out of data in header\n\r"); | ||
89 | exit(); | ||
90 | } | ||
91 | |||
92 | /* Initialize ourself. */ | ||
93 | s.workspace = zalloc(zlib_inflate_workspacesize()); | ||
94 | r = zlib_inflateInit2(&s, -MAX_WBITS); | ||
95 | if (r != Z_OK) { | ||
96 | printf("zlib_inflateInit2 returned %d\n\r", r); | ||
97 | exit(); | ||
98 | } | ||
99 | s.next_in = src + i; | ||
100 | s.avail_in = *lenp - i; | ||
101 | s.next_out = dst; | ||
102 | s.avail_out = dstlen; | ||
103 | r = zlib_inflate(&s, Z_FINISH); | ||
104 | if (r != Z_OK && r != Z_STREAM_END) { | ||
105 | printf("inflate returned %d msg: %s\n\r", r, s.msg); | ||
106 | exit(); | ||
107 | } | ||
108 | *lenp = s.next_out - (unsigned char *) dst; | ||
109 | zlib_inflateEnd(&s); | ||
110 | } | ||
111 | |||
112 | /* Make a bi_rec in OF. We need to be passed a name for BI_BOOTLOADER_ID, | ||
113 | * a machine type for BI_MACHTYPE, and the location where the end of the | ||
114 | * bootloader is (PROG_START + PROG_SIZE) | ||
115 | */ | ||
116 | void make_bi_recs(unsigned long addr, char *name, unsigned int mach, | ||
117 | unsigned long progend) | ||
118 | { | ||
119 | unsigned long sysmap_size; | ||
120 | struct bi_record *rec; | ||
121 | |||
122 | /* Figure out the size of a possible System.map we're going to | ||
123 | * pass along. | ||
124 | * */ | ||
125 | sysmap_size = (unsigned long)(&__sysmap_end) - | ||
126 | (unsigned long)(&__sysmap_begin); | ||
127 | |||
128 | /* leave a 1MB gap then align to the next 1MB boundary */ | ||
129 | addr = _ALIGN(addr+ (1<<20) - 1, (1<<20)); | ||
130 | /* oldworld machine seem very unhappy about this. -- Tom */ | ||
131 | if (addr >= progend) | ||
132 | claim(addr, 0x1000, 0); | ||
133 | |||
134 | rec = (struct bi_record *)addr; | ||
135 | rec->tag = BI_FIRST; | ||
136 | rec->size = sizeof(struct bi_record); | ||
137 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
138 | |||
139 | rec->tag = BI_BOOTLOADER_ID; | ||
140 | sprintf( (char *)rec->data, name); | ||
141 | rec->size = sizeof(struct bi_record) + strlen(name) + 1; | ||
142 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
143 | |||
144 | rec->tag = BI_MACHTYPE; | ||
145 | rec->data[0] = mach; | ||
146 | rec->data[1] = 1; | ||
147 | rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long); | ||
148 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
149 | |||
150 | if (sysmap_size) { | ||
151 | rec->tag = BI_SYSMAP; | ||
152 | rec->data[0] = (unsigned long)(&__sysmap_begin); | ||
153 | rec->data[1] = sysmap_size; | ||
154 | rec->size = sizeof(struct bi_record) + 2 * | ||
155 | sizeof(unsigned long); | ||
156 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
157 | } | ||
158 | |||
159 | rec->tag = BI_LAST; | ||
160 | rec->size = sizeof(struct bi_record); | ||
161 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
162 | } | ||
diff --git a/arch/ppc/boot/openfirmware/dummy.c b/arch/ppc/boot/openfirmware/dummy.c new file mode 100644 index 000000000000..31dbf45bf99c --- /dev/null +++ b/arch/ppc/boot/openfirmware/dummy.c | |||
@@ -0,0 +1,4 @@ | |||
1 | int main(void) | ||
2 | { | ||
3 | return 0; | ||
4 | } | ||
diff --git a/arch/ppc/boot/openfirmware/misc.S b/arch/ppc/boot/openfirmware/misc.S new file mode 100644 index 000000000000..ab9e897cadd0 --- /dev/null +++ b/arch/ppc/boot/openfirmware/misc.S | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | .text | ||
10 | |||
11 | /* | ||
12 | * Use the BAT2 & 3 registers to map the 1st 16MB of RAM to | ||
13 | * the address given as the 1st argument. | ||
14 | */ | ||
15 | .globl setup_bats | ||
16 | setup_bats: | ||
17 | mfpvr 5 | ||
18 | rlwinm 5,5,16,16,31 /* r3 = 1 for 601, 4 for 604 */ | ||
19 | cmpwi 0,5,1 | ||
20 | li 0,0 | ||
21 | bne 4f | ||
22 | mtibatl 3,0 /* invalidate BAT first */ | ||
23 | ori 3,3,4 /* set up BAT registers for 601 */ | ||
24 | li 4,0x7f | ||
25 | mtibatu 2,3 | ||
26 | mtibatl 2,4 | ||
27 | oris 3,3,0x80 | ||
28 | oris 4,4,0x80 | ||
29 | mtibatu 3,3 | ||
30 | mtibatl 3,4 | ||
31 | b 5f | ||
32 | 4: mtdbatu 3,0 /* invalidate BATs first */ | ||
33 | mtibatu 3,0 | ||
34 | ori 3,3,0xff /* set up BAT registers for 604 */ | ||
35 | li 4,2 | ||
36 | mtdbatl 2,4 | ||
37 | mtdbatu 2,3 | ||
38 | mtibatl 2,4 | ||
39 | mtibatu 2,3 | ||
40 | oris 3,3,0x80 | ||
41 | oris 4,4,0x80 | ||
42 | mtdbatl 3,4 | ||
43 | mtdbatu 3,3 | ||
44 | mtibatl 3,4 | ||
45 | mtibatu 3,3 | ||
46 | 5: sync | ||
47 | isync | ||
48 | blr | ||
49 | |||
50 | /* | ||
51 | * Flush the dcache and invalidate the icache for a range of addresses. | ||
52 | * | ||
53 | * flush_cache(addr, len) | ||
54 | */ | ||
55 | .global flush_cache | ||
56 | flush_cache: | ||
57 | addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */ | ||
58 | rlwinm. 4,4,27,5,31 | ||
59 | mtctr 4 | ||
60 | beqlr | ||
61 | 1: dcbf 0,3 | ||
62 | icbi 0,3 | ||
63 | addi 3,3,0x20 | ||
64 | bdnz 1b | ||
65 | sync | ||
66 | isync | ||
67 | blr | ||
diff --git a/arch/ppc/boot/openfirmware/newworldmain.c b/arch/ppc/boot/openfirmware/newworldmain.c new file mode 100644 index 000000000000..fa8a8f9313f9 --- /dev/null +++ b/arch/ppc/boot/openfirmware/newworldmain.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | #include <linux/string.h> | ||
10 | #include "nonstdio.h" | ||
11 | #include "of1275.h" | ||
12 | #include <asm/processor.h> | ||
13 | #include <asm/page.h> | ||
14 | |||
15 | /* Passed from the linker */ | ||
16 | extern char __image_begin, __image_end; | ||
17 | extern char __ramdisk_begin[], __ramdisk_end; | ||
18 | extern char _start, _end; | ||
19 | |||
20 | extern unsigned int heap_max; | ||
21 | extern void flush_cache(void *start, unsigned int len); | ||
22 | extern void gunzip(void *, int, unsigned char *, int *); | ||
23 | extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, | ||
24 | unsigned int progend); | ||
25 | |||
26 | char *avail_ram; | ||
27 | char *begin_avail, *end_avail; | ||
28 | char *avail_high; | ||
29 | |||
30 | |||
31 | #define RAM_END (16 << 20) | ||
32 | |||
33 | #define PROG_START 0x00010000 | ||
34 | #define PROG_SIZE 0x007f0000 | ||
35 | |||
36 | #define SCRATCH_SIZE (128 << 10) | ||
37 | |||
38 | typedef void (*kernel_start_t)(int, int, void *); | ||
39 | |||
40 | void boot(int a1, int a2, void *prom) | ||
41 | { | ||
42 | unsigned sa, len; | ||
43 | void *dst; | ||
44 | unsigned char *im; | ||
45 | unsigned initrd_start, initrd_size; | ||
46 | |||
47 | printf("chrpboot starting: loaded at 0x%p\n", &_start); | ||
48 | |||
49 | initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin); | ||
50 | if (initrd_size) { | ||
51 | initrd_start = (RAM_END - initrd_size) & ~0xFFF; | ||
52 | a1 = initrd_start; | ||
53 | a2 = initrd_size; | ||
54 | claim(initrd_start, RAM_END - initrd_start, 0); | ||
55 | printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r", | ||
56 | initrd_start, (char *)(&__ramdisk_begin), initrd_size); | ||
57 | memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size); | ||
58 | } else | ||
59 | a2 = 0xdeadbeef; | ||
60 | |||
61 | im = (char *)(&__image_begin); | ||
62 | len = (char *)(&__image_end) - (char *)(&__image_begin); | ||
63 | /* claim 3MB starting at PROG_START */ | ||
64 | claim(PROG_START, PROG_SIZE, 0); | ||
65 | dst = (void *) PROG_START; | ||
66 | if (im[0] == 0x1f && im[1] == 0x8b) { | ||
67 | /* claim some memory for scratch space */ | ||
68 | avail_ram = (char *) claim(0, SCRATCH_SIZE, 0x10); | ||
69 | begin_avail = avail_high = avail_ram; | ||
70 | end_avail = avail_ram + SCRATCH_SIZE; | ||
71 | printf("heap at 0x%p\n", avail_ram); | ||
72 | printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len); | ||
73 | gunzip(dst, PROG_SIZE, im, &len); | ||
74 | printf("done %u bytes\n", len); | ||
75 | printf("%u bytes of heap consumed, max in use %u\n", | ||
76 | avail_high - begin_avail, heap_max); | ||
77 | release(begin_avail, SCRATCH_SIZE); | ||
78 | } else { | ||
79 | memmove(dst, im, len); | ||
80 | } | ||
81 | |||
82 | flush_cache(dst, len); | ||
83 | make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_Pmac, | ||
84 | (PROG_START + PROG_SIZE)); | ||
85 | |||
86 | sa = (unsigned long)PROG_START; | ||
87 | printf("start address = 0x%x\n", sa); | ||
88 | |||
89 | (*(kernel_start_t)sa)(a1, a2, prom); | ||
90 | |||
91 | printf("returned?\n"); | ||
92 | |||
93 | pause(); | ||
94 | } | ||
diff --git a/arch/ppc/boot/openfirmware/start.c b/arch/ppc/boot/openfirmware/start.c new file mode 100644 index 000000000000..1617a26956bf --- /dev/null +++ b/arch/ppc/boot/openfirmware/start.c | |||
@@ -0,0 +1,172 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | #include <stdarg.h> | ||
10 | #include "of1275.h" | ||
11 | |||
12 | extern int strlen(const char *s); | ||
13 | extern void boot(int a1, int a2, void *prom); | ||
14 | |||
15 | phandle stdin; | ||
16 | phandle stdout; | ||
17 | phandle stderr; | ||
18 | |||
19 | void printk(char *fmt, ...); | ||
20 | |||
21 | void | ||
22 | start(int a1, int a2, void *promptr) | ||
23 | { | ||
24 | ofinit(promptr); | ||
25 | if (ofstdio(&stdin, &stdout, &stderr)) | ||
26 | exit(); | ||
27 | |||
28 | boot(a1, a2, promptr); | ||
29 | for (;;) | ||
30 | exit(); | ||
31 | } | ||
32 | |||
33 | int writestring(void *f, char *ptr, int nb) | ||
34 | { | ||
35 | int w = 0, i; | ||
36 | char *ret = "\r"; | ||
37 | |||
38 | for (i = 0; i < nb; ++i) { | ||
39 | if (ptr[i] == '\n') { | ||
40 | if (i > w) { | ||
41 | write(f, ptr + w, i - w); | ||
42 | w = i; | ||
43 | } | ||
44 | write(f, ret, 1); | ||
45 | } | ||
46 | } | ||
47 | if (w < nb) | ||
48 | write(f, ptr + w, nb - w); | ||
49 | return nb; | ||
50 | } | ||
51 | |||
52 | int | ||
53 | putc(int c, void *f) | ||
54 | { | ||
55 | char ch = c; | ||
56 | |||
57 | return writestring(f, &ch, 1) == 1? c: -1; | ||
58 | } | ||
59 | |||
60 | int | ||
61 | putchar(int c) | ||
62 | { | ||
63 | return putc(c, stdout); | ||
64 | } | ||
65 | |||
66 | int | ||
67 | fputs(char *str, void *f) | ||
68 | { | ||
69 | int n = strlen(str); | ||
70 | |||
71 | return writestring(f, str, n) == n? 0: -1; | ||
72 | } | ||
73 | |||
74 | int | ||
75 | readchar(void) | ||
76 | { | ||
77 | char ch; | ||
78 | |||
79 | for (;;) { | ||
80 | switch (read(stdin, &ch, 1)) { | ||
81 | case 1: | ||
82 | return ch; | ||
83 | case -1: | ||
84 | printk("read(stdin) returned -1\n"); | ||
85 | return -1; | ||
86 | } | ||
87 | } | ||
88 | } | ||
89 | |||
90 | static char line[256]; | ||
91 | static char *lineptr; | ||
92 | static int lineleft; | ||
93 | |||
94 | int | ||
95 | getchar(void) | ||
96 | { | ||
97 | int c; | ||
98 | |||
99 | if (lineleft == 0) { | ||
100 | lineptr = line; | ||
101 | for (;;) { | ||
102 | c = readchar(); | ||
103 | if (c == -1 || c == 4) | ||
104 | break; | ||
105 | if (c == '\r' || c == '\n') { | ||
106 | *lineptr++ = '\n'; | ||
107 | putchar('\n'); | ||
108 | break; | ||
109 | } | ||
110 | switch (c) { | ||
111 | case 0177: | ||
112 | case '\b': | ||
113 | if (lineptr > line) { | ||
114 | putchar('\b'); | ||
115 | putchar(' '); | ||
116 | putchar('\b'); | ||
117 | --lineptr; | ||
118 | } | ||
119 | break; | ||
120 | case 'U' & 0x1F: | ||
121 | while (lineptr > line) { | ||
122 | putchar('\b'); | ||
123 | putchar(' '); | ||
124 | putchar('\b'); | ||
125 | --lineptr; | ||
126 | } | ||
127 | break; | ||
128 | default: | ||
129 | if (lineptr >= &line[sizeof(line) - 1]) | ||
130 | putchar('\a'); | ||
131 | else { | ||
132 | putchar(c); | ||
133 | *lineptr++ = c; | ||
134 | } | ||
135 | } | ||
136 | } | ||
137 | lineleft = lineptr - line; | ||
138 | lineptr = line; | ||
139 | } | ||
140 | if (lineleft == 0) | ||
141 | return -1; | ||
142 | --lineleft; | ||
143 | return *lineptr++; | ||
144 | } | ||
145 | |||
146 | extern int vsprintf(char *buf, const char *fmt, va_list args); | ||
147 | static char sprint_buf[1024]; | ||
148 | |||
149 | void | ||
150 | printk(char *fmt, ...) | ||
151 | { | ||
152 | va_list args; | ||
153 | int n; | ||
154 | |||
155 | va_start(args, fmt); | ||
156 | n = vsprintf(sprint_buf, fmt, args); | ||
157 | va_end(args); | ||
158 | writestring(stdout, sprint_buf, n); | ||
159 | } | ||
160 | |||
161 | int | ||
162 | printf(char *fmt, ...) | ||
163 | { | ||
164 | va_list args; | ||
165 | int n; | ||
166 | |||
167 | va_start(args, fmt); | ||
168 | n = vsprintf(sprint_buf, fmt, args); | ||
169 | va_end(args); | ||
170 | writestring(stdout, sprint_buf, n); | ||
171 | return n; | ||
172 | } | ||
diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile new file mode 100644 index 000000000000..d8d801fcee10 --- /dev/null +++ b/arch/ppc/boot/simple/Makefile | |||
@@ -0,0 +1,252 @@ | |||
1 | # This is far from simple, but I couldn't think of a good name. This is | ||
2 | # for making the 'zImage' or 'zImage.initrd' on a number of targets. | ||
3 | # | ||
4 | # Author: Tom Rini <trini@mvista.com> | ||
5 | # | ||
6 | # Notes: | ||
7 | # (1) For machines that do not want to use the ELF image directly (including | ||
8 | # stripping just the ELF header off), they must set the variables | ||
9 | # zimage-$(CONFIG_MACHINE) and zimagerd-$(CONFIG_MACHINE) to the target | ||
10 | # that produces the desired image and they must set end-$(CONFIG_MACHINE) | ||
11 | # to what will be suffixed to the image filename. | ||
12 | # (2) Regardless of (1), to have the resulting image be something other | ||
13 | # than 'zImage.elf', set end-$(CONFIG_MACHINE) to be the suffix used for | ||
14 | # the zImage, znetboot, and znetbootrd targets. | ||
15 | # (3) For machine targets which use the mktree program, you can optionally | ||
16 | # set entrypoint-$(CONFIG_MACHINE) to the location which the image should be | ||
17 | # loaded at. The optimal setting for entrypoint-$(CONFIG_MACHINE) is the link | ||
18 | # address. | ||
19 | # (4) It is advisable to pass in the memory size using BI_MEMSIZE and | ||
20 | # get_mem_size(), which is memory controller dependent. Add in the correct | ||
21 | # XXX_memory.o file for this to work, as well as editing the | ||
22 | # misc-$(CONFIG_MACHINE) variable. | ||
23 | |||
24 | boot := arch/ppc/boot | ||
25 | common := $(boot)/common | ||
26 | utils := $(boot)/utils | ||
27 | bootlib := $(boot)/lib | ||
28 | images := $(boot)/images | ||
29 | of1275 := $(boot)/of1275 | ||
30 | tftpboot := /tftpboot | ||
31 | |||
32 | # Normally, we use the 'misc.c' file for decompress_kernel and | ||
33 | # whatnot. Sometimes we need to override this however. | ||
34 | misc-y := misc.o | ||
35 | |||
36 | # Normally, we have our images end in .elf, but something we want to | ||
37 | # change this. | ||
38 | end-y := elf | ||
39 | |||
40 | # Additionally, we normally don't need to mess with the L2 / L3 caches | ||
41 | # if present on 'classic' PPC. | ||
42 | cacheflag-y := -DCLEAR_CACHES="" | ||
43 | # This file will flush / disable the L2, and L3 if present. | ||
44 | clear_L2_L3 := $(srctree)/$(boot)/simple/clear.S | ||
45 | |||
46 | # | ||
47 | # See arch/ppc/kconfig and arch/ppc/platforms/Kconfig | ||
48 | # for definition of what platform each config option refer to. | ||
49 | #---------------------------------------------------------------------------- | ||
50 | zimage-$(CONFIG_CPCI690) := zImage-STRIPELF | ||
51 | zimageinitrd-$(CONFIG_CPCI690) := zImage.initrd-STRIPELF | ||
52 | extra.o-$(CONFIG_CPCI690) := misc-cpci690.o | ||
53 | end-$(CONFIG_CPCI690) := cpci690 | ||
54 | cacheflag-$(CONFIG_CPCI690) := -include $(clear_L2_L3) | ||
55 | |||
56 | zimage-$(CONFIG_IBM_OPENBIOS) := zImage-TREE | ||
57 | zimageinitrd-$(CONFIG_IBM_OPENBIOS) := zImage.initrd-TREE | ||
58 | end-$(CONFIG_IBM_OPENBIOS) := treeboot | ||
59 | misc-$(CONFIG_IBM_OPENBIOS) := misc-embedded.o | ||
60 | |||
61 | end-$(CONFIG_EMBEDDEDBOOT) := embedded | ||
62 | misc-$(CONFIG_EMBEDDEDBOOT) := misc-embedded.o | ||
63 | |||
64 | zimage-$(CONFIG_EBONY) := zImage-TREE | ||
65 | zimageinitrd-$(CONFIG_EBONY) := zImage.initrd-TREE | ||
66 | end-$(CONFIG_EBONY) := ebony | ||
67 | entrypoint-$(CONFIG_EBONY) := 0x01000000 | ||
68 | extra.o-$(CONFIG_EBONY) := openbios.o | ||
69 | |||
70 | zimage-$(CONFIG_LUAN) := zImage-TREE | ||
71 | zimageinitrd-$(CONFIG_LUAN) := zImage.initrd-TREE | ||
72 | end-$(CONFIG_LUAN) := luan | ||
73 | entrypoint-$(CONFIG_LUAN) := 0x01000000 | ||
74 | extra.o-$(CONFIG_LUAN) := pibs.o | ||
75 | |||
76 | zimage-$(CONFIG_OCOTEA) := zImage-TREE | ||
77 | zimageinitrd-$(CONFIG_OCOTEA) := zImage.initrd-TREE | ||
78 | end-$(CONFIG_OCOTEA) := ocotea | ||
79 | entrypoint-$(CONFIG_OCOTEA) := 0x01000000 | ||
80 | extra.o-$(CONFIG_OCOTEA) := pibs.o | ||
81 | |||
82 | extra.o-$(CONFIG_EV64260) := misc-ev64260.o | ||
83 | end-$(CONFIG_EV64260) := ev64260 | ||
84 | cacheflag-$(CONFIG_EV64260) := -include $(clear_L2_L3) | ||
85 | |||
86 | extra.o-$(CONFIG_CHESTNUT) := misc-chestnut.o | ||
87 | end-$(CONFIG_CHESTNUT) := chestnut | ||
88 | |||
89 | zimage-$(CONFIG_GEMINI) := zImage-STRIPELF | ||
90 | zimageinitrd-$(CONFIG_GEMINI) := zImage.initrd-STRIPELF | ||
91 | end-$(CONFIG_GEMINI) := gemini | ||
92 | |||
93 | extra.o-$(CONFIG_K2) := prepmap.o | ||
94 | end-$(CONFIG_K2) := k2 | ||
95 | cacheflag-$(CONFIG_K2) := -include $(clear_L2_L3) | ||
96 | |||
97 | extra.o-$(CONFIG_KATANA) := misc-katana.o | ||
98 | end-$(CONFIG_KATANA) := katana | ||
99 | cacheflag-$(CONFIG_KATANA) := -include $(clear_L2_L3) | ||
100 | |||
101 | extra.o-$(CONFIG_RADSTONE_PPC7D) := misc-radstone_ppc7d.o | ||
102 | end-$(CONFIG_RADSTONE_PPC7D) := radstone_ppc7d | ||
103 | cacheflag-$(CONFIG_RADSTONE_PPC7D) := -include $(clear_L2_L3) | ||
104 | |||
105 | # kconfig 'feature', only one of these will ever be 'y' at a time. | ||
106 | # The rest will be unset. | ||
107 | motorola := $(CONFIG_MCPN765)$(CONFIG_MVME5100)$(CONFIG_PRPMC750) \ | ||
108 | $(CONFIG_PRPMC800)$(CONFIG_LOPEC)$(CONFIG_PPLUS) | ||
109 | motorola := $(strip $(motorola)) | ||
110 | pcore := $(CONFIG_PCORE)$(CONFIG_POWERPMC250) | ||
111 | |||
112 | zimage-$(motorola) := zImage-PPLUS | ||
113 | zimageinitrd-$(motorola) := zImage.initrd-PPLUS | ||
114 | end-$(motorola) := pplus | ||
115 | |||
116 | # Overrides previous assingment | ||
117 | extra.o-$(CONFIG_PPLUS) := prepmap.o | ||
118 | extra.o-$(CONFIG_LOPEC) := mpc10x_memory.o | ||
119 | |||
120 | zimage-$(pcore) := zImage-STRIPELF | ||
121 | zimageinitrd-$(pcore) := zImage.initrd-STRIPELF | ||
122 | extra.o-$(pcore) := chrpmap.o | ||
123 | end-$(pcore) := pcore | ||
124 | cacheflag-$(pcore) := -include $(clear_L2_L3) | ||
125 | |||
126 | zimage-$(CONFIG_PPC_PREP) := zImage-PPLUS | ||
127 | zimageinitrd-$(CONFIG_PPC_PREP) := zImage.initrd-PPLUS | ||
128 | extra.o-$(CONFIG_PPC_PREP) := prepmap.o | ||
129 | misc-$(CONFIG_PPC_PREP) += misc-prep.o mpc10x_memory.o | ||
130 | end-$(CONFIG_PPC_PREP) := prep | ||
131 | |||
132 | end-$(CONFIG_SANDPOINT) := sandpoint | ||
133 | cacheflag-$(CONFIG_SANDPOINT) := -include $(clear_L2_L3) | ||
134 | |||
135 | zimage-$(CONFIG_SPRUCE) := zImage-TREE | ||
136 | zimageinitrd-$(CONFIG_SPRUCE) := zImage.initrd-TREE | ||
137 | end-$(CONFIG_SPRUCE) := spruce | ||
138 | entrypoint-$(CONFIG_SPRUCE) := 0x00800000 | ||
139 | misc-$(CONFIG_SPRUCE) += misc-spruce.o | ||
140 | |||
141 | zimage-$(CONFIG_LITE5200) := zImage-STRIPELF | ||
142 | zimageinitrd-$(CONFIG_LITE5200) := zImage.initrd-STRIPELF | ||
143 | end-$(CONFIG_LITE5200) := lite5200 | ||
144 | cacheflag-$(CONFIG_LITE5200) := -include $(clear_L2_L3) | ||
145 | |||
146 | |||
147 | # SMP images should have a '.smp' suffix. | ||
148 | end-$(CONFIG_SMP) := $(end-y).smp | ||
149 | |||
150 | # This is a treeboot that needs init functions until the | ||
151 | # boot rom is sorted out (i.e. this is short lived) | ||
152 | extra-aflags-$(CONFIG_REDWOOD_4) := -Wa,-m405 | ||
153 | extra.o-$(CONFIG_REDWOOD_4) := rw4/rw4_init.o rw4/rw4_init_brd.o | ||
154 | EXTRA_AFLAGS := $(extra-aflags-y) | ||
155 | # head.o needs to get the cacheflags defined. | ||
156 | AFLAGS_head.o += $(cacheflag-y) | ||
157 | |||
158 | # Linker args. This specifies where the image will be run at. | ||
159 | LD_ARGS := -T $(srctree)/$(boot)/ld.script \ | ||
160 | -Ttext $(CONFIG_BOOT_LOAD) -Bstatic | ||
161 | OBJCOPY_ARGS := -O elf32-powerpc | ||
162 | |||
163 | # head.o and relocate.o must be at the start. | ||
164 | boot-y := head.o relocate.o $(extra.o-y) $(misc-y) | ||
165 | boot-$(CONFIG_40x) += embed_config.o | ||
166 | boot-$(CONFIG_8xx) += embed_config.o | ||
167 | boot-$(CONFIG_8260) += embed_config.o | ||
168 | boot-$(CONFIG_BSEIP) += iic.o | ||
169 | boot-$(CONFIG_MBX) += iic.o pci.o qspan_pci.o | ||
170 | boot-$(CONFIG_MV64X60) += misc-mv64x60.o | ||
171 | boot-$(CONFIG_RPXCLASSIC) += iic.o pci.o qspan_pci.o | ||
172 | boot-$(CONFIG_RPXLITE) += iic.o | ||
173 | # Different boards need different serial implementations. | ||
174 | ifeq ($(CONFIG_SERIAL_CPM_CONSOLE),y) | ||
175 | boot-$(CONFIG_8xx) += m8xx_tty.o | ||
176 | boot-$(CONFIG_8260) += m8260_tty.o | ||
177 | endif | ||
178 | boot-$(CONFIG_SERIAL_MPC52xx_CONSOLE) += mpc52xx_tty.o | ||
179 | boot-$(CONFIG_SERIAL_MPSC_CONSOLE) += mv64x60_tty.o | ||
180 | |||
181 | LIBS := $(common)/lib.a $(bootlib)/lib.a | ||
182 | ifeq ($(CONFIG_PPC_PREP),y) | ||
183 | LIBS += $(of1275)/lib.a | ||
184 | endif | ||
185 | |||
186 | OBJS := $(addprefix $(obj)/,$(boot-y)) | ||
187 | |||
188 | # Tools | ||
189 | MKBUGBOOT := $(utils)/mkbugboot | ||
190 | MKPREP := $(utils)/mkprep | ||
191 | MKTREE := $(utils)/mktree | ||
192 | |||
193 | targets := dummy.o | ||
194 | |||
195 | $(obj)/zvmlinux: $(OBJS) $(LIBS) $(srctree)/$(boot)/ld.script \ | ||
196 | $(images)/vmlinux.gz $(obj)/dummy.o | ||
197 | $(OBJCOPY) $(OBJCOPY_ARGS) \ | ||
198 | --add-section=.image=$(images)/vmlinux.gz \ | ||
199 | --set-section-flags=.image=contents,alloc,load,readonly,data \ | ||
200 | $(obj)/dummy.o $(obj)/image.o | ||
201 | $(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/image.o $(LIBS) | ||
202 | $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab \ | ||
203 | -R .stabstr -R .ramdisk -R .sysmap | ||
204 | |||
205 | $(obj)/zvmlinux.initrd: $(OBJS) $(LIBS) $(srctree)/$(boot)/ld.script \ | ||
206 | $(images)/vmlinux.gz $(obj)/dummy.o | ||
207 | $(OBJCOPY) $(OBJCOPY_ARGS) \ | ||
208 | --add-section=.ramdisk=$(images)/ramdisk.image.gz \ | ||
209 | --set-section-flags=.ramdisk=contents,alloc,load,readonly,data \ | ||
210 | --add-section=.image=$(images)/vmlinux.gz \ | ||
211 | --set-section-flags=.image=contents,alloc,load,readonly,data \ | ||
212 | $(obj)/dummy.o $(obj)/image.o | ||
213 | $(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/image.o $(LIBS) | ||
214 | $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab \ | ||
215 | -R .stabstr -R .sysmap | ||
216 | |||
217 | # Sort-of dummy rules, that let us format the image we want. | ||
218 | zImage: $(images)/$(zimage-y) $(obj)/zvmlinux | ||
219 | cp -f $(obj)/zvmlinux $(images)/zImage.elf | ||
220 | rm -f $(obj)/zvmlinux | ||
221 | |||
222 | zImage.initrd: $(images)/$(zimageinitrd-y) $(obj)/zvmlinux.initrd | ||
223 | cp -f $(obj)/zvmlinux.initrd $(images)/zImage.initrd.elf | ||
224 | rm -f $(obj)/zvmlinux.initrd | ||
225 | |||
226 | znetboot: zImage | ||
227 | cp $(images)/zImage.$(end-y) $(tftpboot)/zImage.$(end-y) | ||
228 | |||
229 | znetboot.initrd: zImage.initrd | ||
230 | cp $(images)/zImage.initrd.$(end-y) $(tftpboot)/zImage.initrd.$(end-y) | ||
231 | |||
232 | $(images)/zImage-STRIPELF: $(obj)/zvmlinux | ||
233 | dd if=$(obj)/zvmlinux of=$(images)/zImage.$(end-y) skip=64 bs=1k | ||
234 | |||
235 | $(images)/zImage.initrd-STRIPELF: $(obj)/zvmlinux.initrd | ||
236 | dd if=$(obj)/zvmlinux.initrd of=$(images)/zImage.initrd.$(end-y) \ | ||
237 | skip=64 bs=1k | ||
238 | |||
239 | $(images)/zImage-TREE: $(obj)/zvmlinux $(MKTREE) | ||
240 | $(MKTREE) $(obj)/zvmlinux $(images)/zImage.$(end-y) $(ENTRYPOINT) | ||
241 | |||
242 | $(images)/zImage.initrd-TREE: $(obj)/zvmlinux.initrd $(MKTREE) | ||
243 | $(MKTREE) $(obj)/zvmlinux.initrd $(images)/zImage.initrd.$(end-y) \ | ||
244 | $(ENTRYPOINT) | ||
245 | |||
246 | $(images)/zImage-PPLUS: $(obj)/zvmlinux $(MKPREP) $(MKBUGBOOT) | ||
247 | $(MKPREP) -pbp $(obj)/zvmlinux $(images)/zImage.$(end-y) | ||
248 | $(MKBUGBOOT) $(obj)/zvmlinux $(images)/zImage.bugboot | ||
249 | |||
250 | $(images)/zImage.initrd-PPLUS: $(obj)/zvmlinux.initrd $(MKPREP) $(MKBUGBOOT) | ||
251 | $(MKPREP) -pbp $(obj)/zvmlinux.initrd $(images)/zImage.initrd.$(end-y) | ||
252 | $(MKBUGBOOT) $(obj)/zvmlinux.initrd $(images)/zImage.initrd.bugboot | ||
diff --git a/arch/ppc/boot/simple/chrpmap.c b/arch/ppc/boot/simple/chrpmap.c new file mode 100644 index 000000000000..14d9e05d98bb --- /dev/null +++ b/arch/ppc/boot/simple/chrpmap.c | |||
@@ -0,0 +1,12 @@ | |||
1 | /* | ||
2 | * 2004 (C) IBM. This file is licensed under the terms of the GNU General | ||
3 | * Public License version 2. This program is licensed "as is" without any | ||
4 | * warranty of any kind, whether express or implied. | ||
5 | */ | ||
6 | |||
7 | #include <nonstdio.h> | ||
8 | |||
9 | void board_isa_init(void) | ||
10 | { | ||
11 | ISA_init(0xFE000000); | ||
12 | } | ||
diff --git a/arch/ppc/boot/simple/clear.S b/arch/ppc/boot/simple/clear.S new file mode 100644 index 000000000000..95c5647a0f51 --- /dev/null +++ b/arch/ppc/boot/simple/clear.S | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * Code to call _setup_L2CR to flus, invalidate and disable the L2, | ||
3 | * and if present, do the same to the L3. | ||
4 | */ | ||
5 | |||
6 | #define CLEAR_CACHES \ | ||
7 | bl _setup_L2CR; \ | ||
8 | \ | ||
9 | /* If 745x, turn off L3CR as well */ \ | ||
10 | mfspr r8,SPRN_PVR; \ | ||
11 | srwi r8,r8,16; \ | ||
12 | \ | ||
13 | cmpli cr0,r8,0x8000; /* 7450 */ \ | ||
14 | cmpli cr1,r8,0x8001; /* 7455 */ \ | ||
15 | cmpli cr2,r8,0x8002; /* 7457 */ \ | ||
16 | /* Now test if any are true. */ \ | ||
17 | cror 4*cr0+eq,4*cr0+eq,4*cr1+eq; \ | ||
18 | cror 4*cr0+eq,4*cr0+eq,4*cr2+eq; \ | ||
19 | beql _setup_L3CR | ||
diff --git a/arch/ppc/boot/simple/cpc700_memory.c b/arch/ppc/boot/simple/cpc700_memory.c new file mode 100644 index 000000000000..8c75cf6c2383 --- /dev/null +++ b/arch/ppc/boot/simple/cpc700_memory.c | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/common/cpc700_memory.c | ||
3 | * | ||
4 | * Find memory based upon settings in the CPC700 bridge | ||
5 | * | ||
6 | * Author: Dan Cox | ||
7 | * | ||
8 | * 2001-2002 (c) MontaVista, Software, Inc. This file is licensed under | ||
9 | * the terms of the GNU General Public License version 2. This program | ||
10 | * is licensed "as is" without any warranty of any kind, whether express | ||
11 | * or implied. | ||
12 | */ | ||
13 | |||
14 | #include <asm/types.h> | ||
15 | #include <asm/io.h> | ||
16 | #include "cpc700.h" | ||
17 | |||
18 | unsigned long | ||
19 | cpc700_get_mem_size(void) | ||
20 | { | ||
21 | int i; | ||
22 | unsigned long len, amt; | ||
23 | |||
24 | /* Start at MB1EA, since MB0EA will most likely be the ending address | ||
25 | for ROM space. */ | ||
26 | for(len = 0, i = CPC700_MB1EA; i <= CPC700_MB4EA; i+=4) { | ||
27 | amt = cpc700_read_memreg(i); | ||
28 | if (amt == 0) | ||
29 | break; | ||
30 | len = amt; | ||
31 | } | ||
32 | |||
33 | return len; | ||
34 | } | ||
35 | |||
36 | |||
diff --git a/arch/ppc/boot/simple/dummy.c b/arch/ppc/boot/simple/dummy.c new file mode 100644 index 000000000000..31dbf45bf99c --- /dev/null +++ b/arch/ppc/boot/simple/dummy.c | |||
@@ -0,0 +1,4 @@ | |||
1 | int main(void) | ||
2 | { | ||
3 | return 0; | ||
4 | } | ||
diff --git a/arch/ppc/boot/simple/embed_config.c b/arch/ppc/boot/simple/embed_config.c new file mode 100644 index 000000000000..c342b47e763e --- /dev/null +++ b/arch/ppc/boot/simple/embed_config.c | |||
@@ -0,0 +1,981 @@ | |||
1 | /* Board specific functions for those embedded 8xx boards that do | ||
2 | * not have boot monitor support for board information. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License as published by the | ||
6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
7 | * option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/types.h> | ||
11 | #include <linux/config.h> | ||
12 | #include <linux/string.h> | ||
13 | #include <asm/reg.h> | ||
14 | #ifdef CONFIG_8xx | ||
15 | #include <asm/mpc8xx.h> | ||
16 | #endif | ||
17 | #ifdef CONFIG_8260 | ||
18 | #include <asm/mpc8260.h> | ||
19 | #include <asm/immap_cpm2.h> | ||
20 | #endif | ||
21 | #ifdef CONFIG_40x | ||
22 | #include <asm/io.h> | ||
23 | #endif | ||
24 | extern unsigned long timebase_period_ns; | ||
25 | |||
26 | /* For those boards that don't provide one. | ||
27 | */ | ||
28 | #if !defined(CONFIG_MBX) | ||
29 | static bd_t bdinfo; | ||
30 | #endif | ||
31 | |||
32 | /* IIC functions. | ||
33 | * These are just the basic master read/write operations so we can | ||
34 | * examine serial EEPROM. | ||
35 | */ | ||
36 | extern void iic_read(uint devaddr, u_char *buf, uint offset, uint count); | ||
37 | |||
38 | /* Supply a default Ethernet address for those eval boards that don't | ||
39 | * ship with one. This is an address from the MBX board I have, so | ||
40 | * it is unlikely you will find it on your network. | ||
41 | */ | ||
42 | static ushort def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 }; | ||
43 | |||
44 | #if defined(CONFIG_MBX) | ||
45 | |||
46 | /* The MBX hands us a pretty much ready to go board descriptor. This | ||
47 | * is where the idea started in the first place. | ||
48 | */ | ||
49 | void | ||
50 | embed_config(bd_t **bdp) | ||
51 | { | ||
52 | u_char *mp; | ||
53 | u_char eebuf[128]; | ||
54 | int i = 8; | ||
55 | bd_t *bd; | ||
56 | |||
57 | bd = *bdp; | ||
58 | |||
59 | /* Read the first 128 bytes of the EEPROM. There is more, | ||
60 | * but this is all we need. | ||
61 | */ | ||
62 | iic_read(0xa4, eebuf, 0, 128); | ||
63 | |||
64 | /* All we are looking for is the Ethernet MAC address. The | ||
65 | * first 8 bytes are 'MOTOROLA', so check for part of that. | ||
66 | * Next, the VPD describes a MAC 'packet' as being of type 08 | ||
67 | * and size 06. So we look for that and the MAC must follow. | ||
68 | * If there are more than one, we still only care about the first. | ||
69 | * If it's there, assume we have a valid MAC address. If not, | ||
70 | * grab our default one. | ||
71 | */ | ||
72 | if ((*(uint *)eebuf) == 0x4d4f544f) { | ||
73 | while (i < 127 && !(eebuf[i] == 0x08 && eebuf[i + 1] == 0x06)) | ||
74 | i += eebuf[i + 1] + 2; /* skip this packet */ | ||
75 | |||
76 | if (i == 127) /* Couldn't find. */ | ||
77 | mp = (u_char *)def_enet_addr; | ||
78 | else | ||
79 | mp = &eebuf[i + 2]; | ||
80 | } | ||
81 | else | ||
82 | mp = (u_char *)def_enet_addr; | ||
83 | |||
84 | for (i=0; i<6; i++) | ||
85 | bd->bi_enetaddr[i] = *mp++; | ||
86 | |||
87 | /* The boot rom passes these to us in MHz. Linux now expects | ||
88 | * them to be in Hz. | ||
89 | */ | ||
90 | bd->bi_intfreq *= 1000000; | ||
91 | bd->bi_busfreq *= 1000000; | ||
92 | |||
93 | /* Stuff a baud rate here as well. | ||
94 | */ | ||
95 | bd->bi_baudrate = 9600; | ||
96 | } | ||
97 | #endif /* CONFIG_MBX */ | ||
98 | |||
99 | #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || \ | ||
100 | defined(CONFIG_RPX8260) || defined(CONFIG_EP405) | ||
101 | /* Helper functions for Embedded Planet boards. | ||
102 | */ | ||
103 | /* Because I didn't find anything that would do this....... | ||
104 | */ | ||
105 | u_char | ||
106 | aschex_to_byte(u_char *cp) | ||
107 | { | ||
108 | u_char byte, c; | ||
109 | |||
110 | c = *cp++; | ||
111 | |||
112 | if ((c >= 'A') && (c <= 'F')) { | ||
113 | c -= 'A'; | ||
114 | c += 10; | ||
115 | } else if ((c >= 'a') && (c <= 'f')) { | ||
116 | c -= 'a'; | ||
117 | c += 10; | ||
118 | } else | ||
119 | c -= '0'; | ||
120 | |||
121 | byte = c * 16; | ||
122 | |||
123 | c = *cp; | ||
124 | |||
125 | if ((c >= 'A') && (c <= 'F')) { | ||
126 | c -= 'A'; | ||
127 | c += 10; | ||
128 | } else if ((c >= 'a') && (c <= 'f')) { | ||
129 | c -= 'a'; | ||
130 | c += 10; | ||
131 | } else | ||
132 | c -= '0'; | ||
133 | |||
134 | byte += c; | ||
135 | |||
136 | return(byte); | ||
137 | } | ||
138 | |||
139 | static void | ||
140 | rpx_eth(bd_t *bd, u_char *cp) | ||
141 | { | ||
142 | int i; | ||
143 | |||
144 | for (i=0; i<6; i++) { | ||
145 | bd->bi_enetaddr[i] = aschex_to_byte(cp); | ||
146 | cp += 2; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | #ifdef CONFIG_RPX8260 | ||
151 | static uint | ||
152 | rpx_baseten(u_char *cp) | ||
153 | { | ||
154 | uint retval; | ||
155 | |||
156 | retval = 0; | ||
157 | |||
158 | while (*cp != '\n') { | ||
159 | retval *= 10; | ||
160 | retval += (*cp) - '0'; | ||
161 | cp++; | ||
162 | } | ||
163 | return(retval); | ||
164 | } | ||
165 | #endif | ||
166 | |||
167 | #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) | ||
168 | static void | ||
169 | rpx_brate(bd_t *bd, u_char *cp) | ||
170 | { | ||
171 | uint rate; | ||
172 | |||
173 | rate = 0; | ||
174 | |||
175 | while (*cp != '\n') { | ||
176 | rate *= 10; | ||
177 | rate += (*cp) - '0'; | ||
178 | cp++; | ||
179 | } | ||
180 | |||
181 | bd->bi_baudrate = rate * 100; | ||
182 | } | ||
183 | |||
184 | static void | ||
185 | rpx_cpuspeed(bd_t *bd, u_char *cp) | ||
186 | { | ||
187 | uint num, den; | ||
188 | |||
189 | num = den = 0; | ||
190 | |||
191 | while (*cp != '\n') { | ||
192 | num *= 10; | ||
193 | num += (*cp) - '0'; | ||
194 | cp++; | ||
195 | if (*cp == '/') { | ||
196 | cp++; | ||
197 | den = (*cp) - '0'; | ||
198 | break; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | /* I don't know why the RPX just can't state the actual | ||
203 | * CPU speed..... | ||
204 | */ | ||
205 | if (den) { | ||
206 | num /= den; | ||
207 | num *= den; | ||
208 | } | ||
209 | bd->bi_intfreq = bd->bi_busfreq = num * 1000000; | ||
210 | |||
211 | /* The 8xx can only run a maximum 50 MHz bus speed (until | ||
212 | * Motorola changes this :-). Greater than 50 MHz parts | ||
213 | * run internal/2 for bus speed. | ||
214 | */ | ||
215 | if (num > 50) | ||
216 | bd->bi_busfreq /= 2; | ||
217 | } | ||
218 | #endif | ||
219 | |||
220 | #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_EP405) | ||
221 | static void | ||
222 | rpx_memsize(bd_t *bd, u_char *cp) | ||
223 | { | ||
224 | uint size; | ||
225 | |||
226 | size = 0; | ||
227 | |||
228 | while (*cp != '\n') { | ||
229 | size *= 10; | ||
230 | size += (*cp) - '0'; | ||
231 | cp++; | ||
232 | } | ||
233 | |||
234 | bd->bi_memsize = size * 1024 * 1024; | ||
235 | } | ||
236 | #endif /* LITE || CLASSIC || EP405 */ | ||
237 | #if defined(CONFIG_EP405) | ||
238 | static void | ||
239 | rpx_nvramsize(bd_t *bd, u_char *cp) | ||
240 | { | ||
241 | uint size; | ||
242 | |||
243 | size = 0; | ||
244 | |||
245 | while (*cp != '\n') { | ||
246 | size *= 10; | ||
247 | size += (*cp) - '0'; | ||
248 | cp++; | ||
249 | } | ||
250 | |||
251 | bd->bi_nvramsize = size * 1024; | ||
252 | } | ||
253 | #endif /* CONFIG_EP405 */ | ||
254 | |||
255 | #endif /* Embedded Planet boards */ | ||
256 | |||
257 | #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) | ||
258 | |||
259 | /* Read the EEPROM on the RPX-Lite board. | ||
260 | */ | ||
261 | void | ||
262 | embed_config(bd_t **bdp) | ||
263 | { | ||
264 | u_char eebuf[256], *cp; | ||
265 | bd_t *bd; | ||
266 | |||
267 | /* Read the first 256 bytes of the EEPROM. I think this | ||
268 | * is really all there is, and I hope if it gets bigger the | ||
269 | * info we want is still up front. | ||
270 | */ | ||
271 | bd = &bdinfo; | ||
272 | *bdp = bd; | ||
273 | |||
274 | #if 1 | ||
275 | iic_read(0xa8, eebuf, 0, 128); | ||
276 | iic_read(0xa8, &eebuf[128], 128, 128); | ||
277 | |||
278 | /* We look for two things, the Ethernet address and the | ||
279 | * serial baud rate. The records are separated by | ||
280 | * newlines. | ||
281 | */ | ||
282 | cp = eebuf; | ||
283 | for (;;) { | ||
284 | if (*cp == 'E') { | ||
285 | cp++; | ||
286 | if (*cp == 'A') { | ||
287 | cp += 2; | ||
288 | rpx_eth(bd, cp); | ||
289 | } | ||
290 | } | ||
291 | if (*cp == 'S') { | ||
292 | cp++; | ||
293 | if (*cp == 'B') { | ||
294 | cp += 2; | ||
295 | rpx_brate(bd, cp); | ||
296 | } | ||
297 | } | ||
298 | if (*cp == 'D') { | ||
299 | cp++; | ||
300 | if (*cp == '1') { | ||
301 | cp += 2; | ||
302 | rpx_memsize(bd, cp); | ||
303 | } | ||
304 | } | ||
305 | if (*cp == 'H') { | ||
306 | cp++; | ||
307 | if (*cp == 'Z') { | ||
308 | cp += 2; | ||
309 | rpx_cpuspeed(bd, cp); | ||
310 | } | ||
311 | } | ||
312 | |||
313 | /* Scan to the end of the record. | ||
314 | */ | ||
315 | while ((*cp != '\n') && (*cp != 0xff)) | ||
316 | cp++; | ||
317 | |||
318 | /* If the next character is a 0 or ff, we are done. | ||
319 | */ | ||
320 | cp++; | ||
321 | if ((*cp == 0) || (*cp == 0xff)) | ||
322 | break; | ||
323 | } | ||
324 | bd->bi_memstart = 0; | ||
325 | #else | ||
326 | /* For boards without initialized EEPROM. | ||
327 | */ | ||
328 | bd->bi_memstart = 0; | ||
329 | bd->bi_memsize = (8 * 1024 * 1024); | ||
330 | bd->bi_intfreq = 48000000; | ||
331 | bd->bi_busfreq = 48000000; | ||
332 | bd->bi_baudrate = 9600; | ||
333 | #endif | ||
334 | } | ||
335 | #endif /* RPXLITE || RPXCLASSIC */ | ||
336 | |||
337 | #ifdef CONFIG_BSEIP | ||
338 | /* Build a board information structure for the BSE ip-Engine. | ||
339 | * There is more to come since we will add some environment | ||
340 | * variables and a function to read them. | ||
341 | */ | ||
342 | void | ||
343 | embed_config(bd_t **bdp) | ||
344 | { | ||
345 | u_char *cp; | ||
346 | int i; | ||
347 | bd_t *bd; | ||
348 | |||
349 | bd = &bdinfo; | ||
350 | *bdp = bd; | ||
351 | |||
352 | /* Baud rate and processor speed will eventually come | ||
353 | * from the environment variables. | ||
354 | */ | ||
355 | bd->bi_baudrate = 9600; | ||
356 | |||
357 | /* Get the Ethernet station address from the Flash ROM. | ||
358 | */ | ||
359 | cp = (u_char *)0xfe003ffa; | ||
360 | for (i=0; i<6; i++) { | ||
361 | bd->bi_enetaddr[i] = *cp++; | ||
362 | } | ||
363 | |||
364 | /* The rest of this should come from the environment as well. | ||
365 | */ | ||
366 | bd->bi_memstart = 0; | ||
367 | bd->bi_memsize = (16 * 1024 * 1024); | ||
368 | bd->bi_intfreq = 48000000; | ||
369 | bd->bi_busfreq = 48000000; | ||
370 | } | ||
371 | #endif /* BSEIP */ | ||
372 | |||
373 | #ifdef CONFIG_FADS | ||
374 | /* Build a board information structure for the FADS. | ||
375 | */ | ||
376 | void | ||
377 | embed_config(bd_t **bdp) | ||
378 | { | ||
379 | u_char *cp; | ||
380 | int i; | ||
381 | bd_t *bd; | ||
382 | |||
383 | bd = &bdinfo; | ||
384 | *bdp = bd; | ||
385 | |||
386 | /* Just fill in some known values. | ||
387 | */ | ||
388 | bd->bi_baudrate = 9600; | ||
389 | |||
390 | /* Use default enet. | ||
391 | */ | ||
392 | cp = (u_char *)def_enet_addr; | ||
393 | for (i=0; i<6; i++) { | ||
394 | bd->bi_enetaddr[i] = *cp++; | ||
395 | } | ||
396 | |||
397 | bd->bi_memstart = 0; | ||
398 | bd->bi_memsize = (8 * 1024 * 1024); | ||
399 | bd->bi_intfreq = 40000000; | ||
400 | bd->bi_busfreq = 40000000; | ||
401 | } | ||
402 | #endif /* FADS */ | ||
403 | |||
404 | #ifdef CONFIG_8260 | ||
405 | /* Compute 8260 clock values if the rom doesn't provide them. | ||
406 | */ | ||
407 | static unsigned char bus2core_8260[] = { | ||
408 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | ||
409 | 3, 2, 2, 2, 4, 4, 5, 9, 6, 11, 8, 10, 3, 12, 7, 2, | ||
410 | 6, 5, 13, 2, 14, 4, 15, 2, 3, 11, 8, 10, 16, 12, 7, 2, | ||
411 | }; | ||
412 | |||
413 | static void | ||
414 | clk_8260(bd_t *bd) | ||
415 | { | ||
416 | uint scmr, vco_out, clkin; | ||
417 | uint plldf, pllmf, corecnf; | ||
418 | volatile cpm2_map_t *ip; | ||
419 | |||
420 | ip = (cpm2_map_t *)CPM_MAP_ADDR; | ||
421 | scmr = ip->im_clkrst.car_scmr; | ||
422 | |||
423 | /* The clkin is always bus frequency. | ||
424 | */ | ||
425 | clkin = bd->bi_busfreq; | ||
426 | |||
427 | /* Collect the bits from the scmr. | ||
428 | */ | ||
429 | plldf = (scmr >> 12) & 1; | ||
430 | pllmf = scmr & 0xfff; | ||
431 | corecnf = (scmr >> 24) &0x1f; | ||
432 | |||
433 | /* This is arithmetic from the 8260 manual. | ||
434 | */ | ||
435 | vco_out = clkin / (plldf + 1); | ||
436 | vco_out *= 2 * (pllmf + 1); | ||
437 | bd->bi_vco = vco_out; /* Save for later */ | ||
438 | |||
439 | bd->bi_cpmfreq = vco_out / 2; /* CPM Freq, in MHz */ | ||
440 | bd->bi_intfreq = bd->bi_busfreq * bus2core_8260[corecnf] / 2; | ||
441 | |||
442 | /* Set Baud rate divisor. The power up default is divide by 16, | ||
443 | * but we set it again here in case it was changed. | ||
444 | */ | ||
445 | ip->im_clkrst.car_sccr = 1; /* DIV 16 BRG */ | ||
446 | bd->bi_brgfreq = vco_out / 16; | ||
447 | } | ||
448 | |||
449 | static unsigned char bus2core_8280[] = { | ||
450 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | ||
451 | 3, 2, 2, 2, 4, 4, 5, 9, 6, 11, 8, 10, 3, 12, 7, 2, | ||
452 | 6, 5, 13, 2, 14, 2, 15, 2, 3, 2, 2, 2, 16, 2, 2, 2, | ||
453 | }; | ||
454 | |||
455 | static void | ||
456 | clk_8280(bd_t *bd) | ||
457 | { | ||
458 | uint scmr, main_clk, clkin; | ||
459 | uint pllmf, corecnf; | ||
460 | volatile cpm2_map_t *ip; | ||
461 | |||
462 | ip = (cpm2_map_t *)CPM_MAP_ADDR; | ||
463 | scmr = ip->im_clkrst.car_scmr; | ||
464 | |||
465 | /* The clkin is always bus frequency. | ||
466 | */ | ||
467 | clkin = bd->bi_busfreq; | ||
468 | |||
469 | /* Collect the bits from the scmr. | ||
470 | */ | ||
471 | pllmf = scmr & 0xf; | ||
472 | corecnf = (scmr >> 24) & 0x1f; | ||
473 | |||
474 | /* This is arithmetic from the 8280 manual. | ||
475 | */ | ||
476 | main_clk = clkin * (pllmf + 1); | ||
477 | |||
478 | bd->bi_cpmfreq = main_clk / 2; /* CPM Freq, in MHz */ | ||
479 | bd->bi_intfreq = bd->bi_busfreq * bus2core_8280[corecnf] / 2; | ||
480 | |||
481 | /* Set Baud rate divisor. The power up default is divide by 16, | ||
482 | * but we set it again here in case it was changed. | ||
483 | */ | ||
484 | ip->im_clkrst.car_sccr = (ip->im_clkrst.car_sccr & 0x3) | 0x1; | ||
485 | bd->bi_brgfreq = main_clk / 16; | ||
486 | } | ||
487 | #endif | ||
488 | |||
489 | #ifdef CONFIG_SBC82xx | ||
490 | void | ||
491 | embed_config(bd_t **bdp) | ||
492 | { | ||
493 | u_char *cp; | ||
494 | int i; | ||
495 | bd_t *bd; | ||
496 | unsigned long pvr; | ||
497 | |||
498 | bd = *bdp; | ||
499 | |||
500 | bd = &bdinfo; | ||
501 | *bdp = bd; | ||
502 | bd->bi_baudrate = 9600; | ||
503 | bd->bi_memsize = 256 * 1024 * 1024; /* just a guess */ | ||
504 | |||
505 | cp = (void*)SBC82xx_MACADDR_NVRAM_SCC1; | ||
506 | memcpy(bd->bi_enetaddr, cp, 6); | ||
507 | |||
508 | /* can busfreq be calculated? */ | ||
509 | pvr = mfspr(SPRN_PVR); | ||
510 | if ((pvr & 0xffff0000) == 0x80820000) { | ||
511 | bd->bi_busfreq = 100000000; | ||
512 | clk_8280(bd); | ||
513 | } else { | ||
514 | bd->bi_busfreq = 66000000; | ||
515 | clk_8260(bd); | ||
516 | } | ||
517 | |||
518 | } | ||
519 | #endif /* SBC82xx */ | ||
520 | |||
521 | #if defined(CONFIG_EST8260) || defined(CONFIG_TQM8260) | ||
522 | void | ||
523 | embed_config(bd_t **bdp) | ||
524 | { | ||
525 | u_char *cp; | ||
526 | int i; | ||
527 | bd_t *bd; | ||
528 | |||
529 | bd = *bdp; | ||
530 | #if 0 | ||
531 | /* This is actually provided by my boot rom. I have it | ||
532 | * here for those people that may load the kernel with | ||
533 | * a JTAG/COP tool and not the rom monitor. | ||
534 | */ | ||
535 | bd->bi_baudrate = 115200; | ||
536 | bd->bi_intfreq = 200000000; | ||
537 | bd->bi_busfreq = 66666666; | ||
538 | bd->bi_cpmfreq = 66666666; | ||
539 | bd->bi_brgfreq = 33333333; | ||
540 | bd->bi_memsize = 16 * 1024 * 1024; | ||
541 | #else | ||
542 | /* The boot rom passes these to us in MHz. Linux now expects | ||
543 | * them to be in Hz. | ||
544 | */ | ||
545 | bd->bi_intfreq *= 1000000; | ||
546 | bd->bi_busfreq *= 1000000; | ||
547 | bd->bi_cpmfreq *= 1000000; | ||
548 | bd->bi_brgfreq *= 1000000; | ||
549 | #endif | ||
550 | |||
551 | cp = (u_char *)def_enet_addr; | ||
552 | for (i=0; i<6; i++) { | ||
553 | bd->bi_enetaddr[i] = *cp++; | ||
554 | } | ||
555 | } | ||
556 | #endif /* EST8260 */ | ||
557 | |||
558 | #ifdef CONFIG_SBS8260 | ||
559 | void | ||
560 | embed_config(bd_t **bdp) | ||
561 | { | ||
562 | u_char *cp; | ||
563 | int i; | ||
564 | bd_t *bd; | ||
565 | |||
566 | /* This should provided by the boot rom. | ||
567 | */ | ||
568 | bd = &bdinfo; | ||
569 | *bdp = bd; | ||
570 | bd->bi_baudrate = 9600; | ||
571 | bd->bi_memsize = 64 * 1024 * 1024; | ||
572 | |||
573 | /* Set all of the clocks. We have to know the speed of the | ||
574 | * external clock. The development board had 66 MHz. | ||
575 | */ | ||
576 | bd->bi_busfreq = 66666666; | ||
577 | clk_8260(bd); | ||
578 | |||
579 | /* I don't know how to compute this yet. | ||
580 | */ | ||
581 | bd->bi_intfreq = 133000000; | ||
582 | |||
583 | |||
584 | cp = (u_char *)def_enet_addr; | ||
585 | for (i=0; i<6; i++) { | ||
586 | bd->bi_enetaddr[i] = *cp++; | ||
587 | } | ||
588 | } | ||
589 | #endif /* SBS8260 */ | ||
590 | |||
591 | #ifdef CONFIG_RPX8260 | ||
592 | void | ||
593 | embed_config(bd_t **bdp) | ||
594 | { | ||
595 | u_char *cp, *keyvals; | ||
596 | int i; | ||
597 | bd_t *bd; | ||
598 | |||
599 | keyvals = (u_char *)*bdp; | ||
600 | |||
601 | bd = &bdinfo; | ||
602 | *bdp = bd; | ||
603 | |||
604 | /* This is almost identical to the RPX-Lite/Classic functions | ||
605 | * on the 8xx boards. It would be nice to have a key lookup | ||
606 | * function in a string, but the format of all of the fields | ||
607 | * is slightly different. | ||
608 | */ | ||
609 | cp = keyvals; | ||
610 | for (;;) { | ||
611 | if (*cp == 'E') { | ||
612 | cp++; | ||
613 | if (*cp == 'A') { | ||
614 | cp += 2; | ||
615 | rpx_eth(bd, cp); | ||
616 | } | ||
617 | } | ||
618 | if (*cp == 'S') { | ||
619 | cp++; | ||
620 | if (*cp == 'B') { | ||
621 | cp += 2; | ||
622 | bd->bi_baudrate = rpx_baseten(cp); | ||
623 | } | ||
624 | } | ||
625 | if (*cp == 'D') { | ||
626 | cp++; | ||
627 | if (*cp == '1') { | ||
628 | cp += 2; | ||
629 | bd->bi_memsize = rpx_baseten(cp) * 1024 * 1024; | ||
630 | } | ||
631 | } | ||
632 | if (*cp == 'X') { | ||
633 | cp++; | ||
634 | if (*cp == 'T') { | ||
635 | cp += 2; | ||
636 | bd->bi_busfreq = rpx_baseten(cp); | ||
637 | } | ||
638 | } | ||
639 | if (*cp == 'N') { | ||
640 | cp++; | ||
641 | if (*cp == 'V') { | ||
642 | cp += 2; | ||
643 | bd->bi_nvsize = rpx_baseten(cp) * 1024 * 1024; | ||
644 | } | ||
645 | } | ||
646 | |||
647 | /* Scan to the end of the record. | ||
648 | */ | ||
649 | while ((*cp != '\n') && (*cp != 0xff)) | ||
650 | cp++; | ||
651 | |||
652 | /* If the next character is a 0 or ff, we are done. | ||
653 | */ | ||
654 | cp++; | ||
655 | if ((*cp == 0) || (*cp == 0xff)) | ||
656 | break; | ||
657 | } | ||
658 | bd->bi_memstart = 0; | ||
659 | |||
660 | /* The memory size includes both the 60x and local bus DRAM. | ||
661 | * I don't want to use the local bus DRAM for real memory, | ||
662 | * so subtract it out. It would be nice if they were separate | ||
663 | * keys. | ||
664 | */ | ||
665 | bd->bi_memsize -= 32 * 1024 * 1024; | ||
666 | |||
667 | /* Set all of the clocks. We have to know the speed of the | ||
668 | * external clock. | ||
669 | */ | ||
670 | clk_8260(bd); | ||
671 | |||
672 | /* I don't know how to compute this yet. | ||
673 | */ | ||
674 | bd->bi_intfreq = 200000000; | ||
675 | } | ||
676 | #endif /* RPX6 for testing */ | ||
677 | |||
678 | #ifdef CONFIG_ADS8260 | ||
679 | void | ||
680 | embed_config(bd_t **bdp) | ||
681 | { | ||
682 | u_char *cp; | ||
683 | int i; | ||
684 | bd_t *bd; | ||
685 | |||
686 | /* This should provided by the boot rom. | ||
687 | */ | ||
688 | bd = &bdinfo; | ||
689 | *bdp = bd; | ||
690 | bd->bi_baudrate = 9600; | ||
691 | bd->bi_memsize = 16 * 1024 * 1024; | ||
692 | |||
693 | /* Set all of the clocks. We have to know the speed of the | ||
694 | * external clock. The development board had 66 MHz. | ||
695 | */ | ||
696 | bd->bi_busfreq = 66666666; | ||
697 | clk_8260(bd); | ||
698 | |||
699 | /* I don't know how to compute this yet. | ||
700 | */ | ||
701 | bd->bi_intfreq = 200000000; | ||
702 | |||
703 | |||
704 | cp = (u_char *)def_enet_addr; | ||
705 | for (i=0; i<6; i++) { | ||
706 | bd->bi_enetaddr[i] = *cp++; | ||
707 | } | ||
708 | } | ||
709 | #endif /* ADS8260 */ | ||
710 | |||
711 | #ifdef CONFIG_WILLOW | ||
712 | void | ||
713 | embed_config(bd_t **bdp) | ||
714 | { | ||
715 | u_char *cp; | ||
716 | int i; | ||
717 | bd_t *bd; | ||
718 | |||
719 | /* Willow has Open Firmware....I should learn how to get this | ||
720 | * information from it. | ||
721 | */ | ||
722 | bd = &bdinfo; | ||
723 | *bdp = bd; | ||
724 | bd->bi_baudrate = 9600; | ||
725 | bd->bi_memsize = 32 * 1024 * 1024; | ||
726 | |||
727 | /* Set all of the clocks. We have to know the speed of the | ||
728 | * external clock. The development board had 66 MHz. | ||
729 | */ | ||
730 | bd->bi_busfreq = 66666666; | ||
731 | clk_8260(bd); | ||
732 | |||
733 | /* I don't know how to compute this yet. | ||
734 | */ | ||
735 | bd->bi_intfreq = 200000000; | ||
736 | |||
737 | |||
738 | cp = (u_char *)def_enet_addr; | ||
739 | for (i=0; i<6; i++) { | ||
740 | bd->bi_enetaddr[i] = *cp++; | ||
741 | } | ||
742 | } | ||
743 | #endif /* WILLOW */ | ||
744 | |||
745 | #ifdef CONFIG_XILINX_ML300 | ||
746 | void | ||
747 | embed_config(bd_t ** bdp) | ||
748 | { | ||
749 | static const unsigned long line_size = 32; | ||
750 | static const unsigned long congruence_classes = 256; | ||
751 | unsigned long addr; | ||
752 | unsigned long dccr; | ||
753 | bd_t *bd; | ||
754 | |||
755 | /* | ||
756 | * Invalidate the data cache if the data cache is turned off. | ||
757 | * - The 405 core does not invalidate the data cache on power-up | ||
758 | * or reset but does turn off the data cache. We cannot assume | ||
759 | * that the cache contents are valid. | ||
760 | * - If the data cache is turned on this must have been done by | ||
761 | * a bootloader and we assume that the cache contents are | ||
762 | * valid. | ||
763 | */ | ||
764 | __asm__("mfdccr %0": "=r" (dccr)); | ||
765 | if (dccr == 0) { | ||
766 | for (addr = 0; | ||
767 | addr < (congruence_classes * line_size); | ||
768 | addr += line_size) { | ||
769 | __asm__("dccci 0,%0": :"b"(addr)); | ||
770 | } | ||
771 | } | ||
772 | |||
773 | bd = &bdinfo; | ||
774 | *bdp = bd; | ||
775 | bd->bi_memsize = XPAR_DDR_0_SIZE; | ||
776 | bd->bi_intfreq = XPAR_CORE_CLOCK_FREQ_HZ; | ||
777 | bd->bi_busfreq = XPAR_PLB_CLOCK_FREQ_HZ; | ||
778 | bd->bi_pci_busfreq = XPAR_PCI_0_CLOCK_FREQ_HZ; | ||
779 | timebase_period_ns = 1000000000 / bd->bi_tbfreq; | ||
780 | /* see bi_tbfreq definition in arch/ppc/platforms/4xx/xilinx_ml300.h */ | ||
781 | } | ||
782 | #endif /* CONFIG_XILINX_ML300 */ | ||
783 | |||
784 | #ifdef CONFIG_IBM_OPENBIOS | ||
785 | /* This could possibly work for all treeboot roms. | ||
786 | */ | ||
787 | #if defined(CONFIG_ASH) || defined(CONFIG_BEECH) || defined(CONFIG_BUBINGA) | ||
788 | #define BOARD_INFO_VECTOR 0xFFF80B50 /* openbios 1.19 moved this vector down - armin */ | ||
789 | #else | ||
790 | #define BOARD_INFO_VECTOR 0xFFFE0B50 | ||
791 | #endif | ||
792 | |||
793 | #ifdef CONFIG_BEECH | ||
794 | static void | ||
795 | get_board_info(bd_t **bdp) | ||
796 | { | ||
797 | typedef void (*PFV)(bd_t *bd); | ||
798 | ((PFV)(*(unsigned long *)BOARD_INFO_VECTOR))(*bdp); | ||
799 | return; | ||
800 | } | ||
801 | |||
802 | void | ||
803 | embed_config(bd_t **bdp) | ||
804 | { | ||
805 | *bdp = &bdinfo; | ||
806 | get_board_info(bdp); | ||
807 | } | ||
808 | #else /* !CONFIG_BEECH */ | ||
809 | void | ||
810 | embed_config(bd_t **bdp) | ||
811 | { | ||
812 | u_char *cp; | ||
813 | int i; | ||
814 | bd_t *bd, *treeboot_bd; | ||
815 | bd_t *(*get_board_info)(void) = | ||
816 | (bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR); | ||
817 | #if !defined(CONFIG_STB03xxx) | ||
818 | |||
819 | /* shut down the Ethernet controller that the boot rom | ||
820 | * sometimes leaves running. | ||
821 | */ | ||
822 | mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); /* 1st reset MAL */ | ||
823 | while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for the reset */ | ||
824 | out_be32((volatile u32*)EMAC0_BASE,0x20000000); /* then reset EMAC */ | ||
825 | #endif | ||
826 | |||
827 | bd = &bdinfo; | ||
828 | *bdp = bd; | ||
829 | if ((treeboot_bd = get_board_info()) != NULL) { | ||
830 | memcpy(bd, treeboot_bd, sizeof(bd_t)); | ||
831 | } | ||
832 | else { | ||
833 | /* Hmmm...better try to stuff some defaults. | ||
834 | */ | ||
835 | bd->bi_memsize = 16 * 1024 * 1024; | ||
836 | cp = (u_char *)def_enet_addr; | ||
837 | for (i=0; i<6; i++) { | ||
838 | /* I should probably put different ones here, | ||
839 | * hopefully only one is used. | ||
840 | */ | ||
841 | bd->BD_EMAC_ADDR(0,i) = *cp; | ||
842 | |||
843 | #ifdef CONFIG_PCI | ||
844 | bd->bi_pci_enetaddr[i] = *cp++; | ||
845 | #endif | ||
846 | } | ||
847 | bd->bi_tbfreq = 200 * 1000 * 1000; | ||
848 | bd->bi_intfreq = 200000000; | ||
849 | bd->bi_busfreq = 100000000; | ||
850 | #ifdef CONFIG_PCI | ||
851 | bd->bi_pci_busfreq = 66666666; | ||
852 | #endif | ||
853 | } | ||
854 | /* Yeah, this look weird, but on Redwood 4 they are | ||
855 | * different object in the structure. Sincr Redwwood 5 | ||
856 | * and Redwood 6 use OpenBIOS, it requires a special value. | ||
857 | */ | ||
858 | #if defined(CONFIG_REDWOOD_5) || defined (CONFIG_REDWOOD_6) | ||
859 | bd->bi_tbfreq = 27 * 1000 * 1000; | ||
860 | #endif | ||
861 | timebase_period_ns = 1000000000 / bd->bi_tbfreq; | ||
862 | } | ||
863 | #endif /* CONFIG_BEECH */ | ||
864 | #endif /* CONFIG_IBM_OPENBIOS */ | ||
865 | |||
866 | #ifdef CONFIG_EP405 | ||
867 | #include <linux/serial_reg.h> | ||
868 | |||
869 | void | ||
870 | embed_config(bd_t **bdp) | ||
871 | { | ||
872 | u32 chcr0; | ||
873 | u_char *cp; | ||
874 | bd_t *bd; | ||
875 | |||
876 | /* Different versions of the PlanetCore firmware vary in how | ||
877 | they set up the serial port - in particular whether they | ||
878 | use the internal or external serial clock for UART0. Make | ||
879 | sure the UART is in a known state. */ | ||
880 | /* FIXME: We should use the board's 11.0592MHz external serial | ||
881 | clock - it will be more accurate for serial rates. For | ||
882 | now, however the baud rates in ep405.h are for the internal | ||
883 | clock. */ | ||
884 | chcr0 = mfdcr(DCRN_CHCR0); | ||
885 | if ( (chcr0 & 0x1fff) != 0x103e ) { | ||
886 | mtdcr(DCRN_CHCR0, (chcr0 & 0xffffe000) | 0x103e); | ||
887 | /* The following tricks serial_init() into resetting the baud rate */ | ||
888 | writeb(0, UART0_IO_BASE + UART_LCR); | ||
889 | } | ||
890 | |||
891 | /* We haven't seen actual problems with the EP405 leaving the | ||
892 | * EMAC running (as we have on Walnut). But the registers | ||
893 | * suggest it may not be left completely quiescent. Reset it | ||
894 | * just to be sure. */ | ||
895 | mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); /* 1st reset MAL */ | ||
896 | while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for the reset */ | ||
897 | out_be32((unsigned *)EMAC0_BASE,0x20000000); /* then reset EMAC */ | ||
898 | |||
899 | bd = &bdinfo; | ||
900 | *bdp = bd; | ||
901 | #if 1 | ||
902 | cp = (u_char *)0xF0000EE0; | ||
903 | for (;;) { | ||
904 | if (*cp == 'E') { | ||
905 | cp++; | ||
906 | if (*cp == 'A') { | ||
907 | cp += 2; | ||
908 | rpx_eth(bd, cp); | ||
909 | } | ||
910 | } | ||
911 | |||
912 | if (*cp == 'D') { | ||
913 | cp++; | ||
914 | if (*cp == '1') { | ||
915 | cp += 2; | ||
916 | rpx_memsize(bd, cp); | ||
917 | } | ||
918 | } | ||
919 | |||
920 | if (*cp == 'N') { | ||
921 | cp++; | ||
922 | if (*cp == 'V') { | ||
923 | cp += 2; | ||
924 | rpx_nvramsize(bd, cp); | ||
925 | } | ||
926 | } | ||
927 | while ((*cp != '\n') && (*cp != 0xff)) | ||
928 | cp++; | ||
929 | |||
930 | cp++; | ||
931 | if ((*cp == 0) || (*cp == 0xff)) | ||
932 | break; | ||
933 | } | ||
934 | bd->bi_intfreq = 200000000; | ||
935 | bd->bi_busfreq = 100000000; | ||
936 | bd->bi_pci_busfreq= 33000000 ; | ||
937 | #else | ||
938 | |||
939 | bd->bi_memsize = 64000000; | ||
940 | bd->bi_intfreq = 200000000; | ||
941 | bd->bi_busfreq = 100000000; | ||
942 | bd->bi_pci_busfreq= 33000000 ; | ||
943 | #endif | ||
944 | } | ||
945 | #endif | ||
946 | |||
947 | #ifdef CONFIG_RAINIER | ||
948 | /* Rainier uses vxworks bootrom */ | ||
949 | void | ||
950 | embed_config(bd_t **bdp) | ||
951 | { | ||
952 | u_char *cp; | ||
953 | int i; | ||
954 | bd_t *bd; | ||
955 | |||
956 | bd = &bdinfo; | ||
957 | *bdp = bd; | ||
958 | |||
959 | for(i=0;i<8192;i+=32) { | ||
960 | __asm__("dccci 0,%0" :: "r" (i)); | ||
961 | } | ||
962 | __asm__("iccci 0,0"); | ||
963 | __asm__("sync;isync"); | ||
964 | |||
965 | /* init ram for parity */ | ||
966 | memset(0, 0,0x400000); /* Lo memory */ | ||
967 | |||
968 | |||
969 | bd->bi_memsize = (32 * 1024 * 1024) ; | ||
970 | bd->bi_intfreq = 133000000; //the internal clock is 133 MHz | ||
971 | bd->bi_busfreq = 100000000; | ||
972 | bd->bi_pci_busfreq= 33000000; | ||
973 | |||
974 | cp = (u_char *)def_enet_addr; | ||
975 | for (i=0; i<6; i++) { | ||
976 | bd->bi_enetaddr[i] = *cp++; | ||
977 | } | ||
978 | |||
979 | } | ||
980 | #endif | ||
981 | |||
diff --git a/arch/ppc/boot/simple/head.S b/arch/ppc/boot/simple/head.S new file mode 100644 index 000000000000..524053202bb4 --- /dev/null +++ b/arch/ppc/boot/simple/head.S | |||
@@ -0,0 +1,142 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/head.S | ||
3 | * | ||
4 | * Initial board bringup code for many different boards. | ||
5 | * | ||
6 | * Author: Tom Rini | ||
7 | * trini@mvista.com | ||
8 | * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others). | ||
9 | * | ||
10 | * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under | ||
11 | * the terms of the GNU General Public License version 2. This program | ||
12 | * is licensed "as is" without any warranty of any kind, whether express | ||
13 | * or implied. | ||
14 | */ | ||
15 | |||
16 | #include <linux/config.h> | ||
17 | #include <asm/reg.h> | ||
18 | #include <asm/cache.h> | ||
19 | #include <asm/ppc_asm.h> | ||
20 | |||
21 | .text | ||
22 | |||
23 | /* | ||
24 | * Begin at some arbitrary location in RAM or Flash | ||
25 | * Initialize core registers | ||
26 | * Configure memory controller (Not executing from RAM) | ||
27 | * Move the boot code to the link address (8M) | ||
28 | * Setup C stack | ||
29 | * Initialize UART | ||
30 | * Decompress the kernel to 0x0 | ||
31 | * Jump to the kernel entry | ||
32 | * | ||
33 | */ | ||
34 | |||
35 | .globl start | ||
36 | start: | ||
37 | bl start_ | ||
38 | #ifdef CONFIG_IBM_OPENBIOS | ||
39 | /* The IBM "Tree" bootrom knows that the address of the bootrom | ||
40 | * read only structure is 4 bytes after _start. | ||
41 | */ | ||
42 | .long 0x62726f6d # structure ID - "brom" | ||
43 | .long 0x5f726f00 # - "_ro\0" | ||
44 | .long 1 # structure version | ||
45 | .long bootrom_cmdline # address of *bootrom_cmdline | ||
46 | #endif | ||
47 | |||
48 | start_: | ||
49 | #ifdef CONFIG_FORCE | ||
50 | /* We have some really bad firmware. We must disable the L1 | ||
51 | * icache/dcache now or the board won't boot. | ||
52 | */ | ||
53 | li r4,0x0000 | ||
54 | isync | ||
55 | mtspr SPRN_HID0,r4 | ||
56 | sync | ||
57 | isync | ||
58 | #endif | ||
59 | |||
60 | #if defined(CONFIG_MBX) || defined(CONFIG_RPX8260) || defined(CONFIG_PPC_PREP) | ||
61 | mr r29,r3 /* On the MBX860, r3 is the board info pointer. | ||
62 | * On the RPXSUPER, r3 points to the NVRAM | ||
63 | * configuration keys. | ||
64 | * On PReP, r3 is the pointer to the residual data. | ||
65 | */ | ||
66 | #endif | ||
67 | |||
68 | mflr r3 /* Save our actual starting address. */ | ||
69 | |||
70 | /* The following functions we call must not modify r3 or r4..... | ||
71 | */ | ||
72 | #ifdef CONFIG_6xx | ||
73 | /* On PReP we must look at the OpenFirmware pointer and sanity | ||
74 | * test it. On other platforms, we disable the MMU right now | ||
75 | * and other bits. | ||
76 | */ | ||
77 | #ifdef CONFIG_PPC_PREP | ||
78 | /* | ||
79 | * Save the OF pointer to r25, but only if the entry point is in a sane | ||
80 | * location; if not we store 0. If there is no entry point, or it is | ||
81 | * invalid, we establish the default MSR value immediately. Otherwise, | ||
82 | * we defer doing that, to allow OF functions to be called, until we | ||
83 | * begin uncompressing the kernel. | ||
84 | */ | ||
85 | lis r8,0x0fff /* r8 = 0x0fffffff */ | ||
86 | ori r8,r8,0xffff | ||
87 | |||
88 | subc r8,r8,r5 /* r8 = (r5 <= r8) ? ~0 : 0 */ | ||
89 | subfe r8,r8,r8 | ||
90 | nand r8,r8,r8 | ||
91 | |||
92 | and. r5,r5,r8 /* r5 will be cleared if (r5 > r8) */ | ||
93 | bne+ haveOF | ||
94 | |||
95 | li r8,MSR_IP|MSR_FP /* Not OF: set MSR immediately */ | ||
96 | mtmsr r8 | ||
97 | isync | ||
98 | haveOF: | ||
99 | mr r25,r5 | ||
100 | #else | ||
101 | bl disable_6xx_mmu | ||
102 | #endif | ||
103 | bl disable_6xx_l1cache | ||
104 | |||
105 | CLEAR_CACHES | ||
106 | #endif | ||
107 | |||
108 | #ifdef CONFIG_8xx | ||
109 | mfmsr r8 /* Turn off interrupts */ | ||
110 | li r9,0 | ||
111 | ori r9,r9,MSR_EE | ||
112 | andc r8,r8,r9 | ||
113 | mtmsr r8 | ||
114 | |||
115 | /* We do this because some boot roms don't initialize the | ||
116 | * processor correctly. Don't do this if you want to debug | ||
117 | * using a BDM device. | ||
118 | */ | ||
119 | li r4,0 /* Zero DER to prevent FRZ */ | ||
120 | mtspr SPRN_DER,r4 | ||
121 | #endif | ||
122 | |||
123 | #ifdef CONFIG_REDWOOD_4 | ||
124 | /* All of this Redwood 4 stuff will soon disappear when the | ||
125 | * boot rom is straightened out. | ||
126 | */ | ||
127 | mr r29, r3 /* Easier than changing the other code */ | ||
128 | bl HdwInit | ||
129 | mr r3, r29 | ||
130 | #endif | ||
131 | |||
132 | #if defined(CONFIG_MBX) || defined(CONFIG_RPX8260) || defined(CONFIG_PPC_PREP) | ||
133 | mr r4,r29 /* put the board info pointer where the relocate | ||
134 | * routine will find it | ||
135 | */ | ||
136 | #endif | ||
137 | |||
138 | /* Get the load address. | ||
139 | */ | ||
140 | subi r3, r3, 4 /* Get the actual IP, not NIP */ | ||
141 | b relocate | ||
142 | |||
diff --git a/arch/ppc/boot/simple/iic.c b/arch/ppc/boot/simple/iic.c new file mode 100644 index 000000000000..e4efd838bfaa --- /dev/null +++ b/arch/ppc/boot/simple/iic.c | |||
@@ -0,0 +1,214 @@ | |||
1 | /* Minimal support functions to read configuration from IIC EEPROMS | ||
2 | * on MPC8xx boards. Originally written for RPGC RPX-Lite. | ||
3 | * Dan Malek (dmalek@jlc.net). | ||
4 | */ | ||
5 | #include <linux/types.h> | ||
6 | #include <asm/uaccess.h> | ||
7 | #include <asm/mpc8xx.h> | ||
8 | #include <asm/commproc.h> | ||
9 | |||
10 | |||
11 | /* IIC functions. | ||
12 | * These are just the basic master read/write operations so we can | ||
13 | * examine serial EEPROM. | ||
14 | */ | ||
15 | void iic_read(uint devaddr, u_char *buf, uint offset, uint count); | ||
16 | |||
17 | static int iic_init_done; | ||
18 | |||
19 | static void | ||
20 | iic_init(void) | ||
21 | { | ||
22 | volatile iic_t *iip; | ||
23 | volatile i2c8xx_t *i2c; | ||
24 | volatile cpm8xx_t *cp; | ||
25 | volatile immap_t *immap; | ||
26 | uint dpaddr; | ||
27 | |||
28 | immap = (immap_t *)IMAP_ADDR; | ||
29 | cp = (cpm8xx_t *)&(immap->im_cpm); | ||
30 | |||
31 | /* Reset the CPM. This is necessary on the 860 processors | ||
32 | * that may have started the SCC1 ethernet without relocating | ||
33 | * the IIC. | ||
34 | * This also stops the Ethernet in case we were loaded by a | ||
35 | * BOOTP rom monitor. | ||
36 | */ | ||
37 | cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG); | ||
38 | |||
39 | /* Wait for it. | ||
40 | */ | ||
41 | while (cp->cp_cpcr & (CPM_CR_RST | CPM_CR_FLG)); | ||
42 | |||
43 | /* Remove any microcode patches. We will install our own | ||
44 | * later. | ||
45 | */ | ||
46 | cp->cp_cpmcr1 = 0; | ||
47 | cp->cp_cpmcr2 = 0; | ||
48 | cp->cp_cpmcr3 = 0; | ||
49 | cp->cp_cpmcr4 = 0; | ||
50 | cp->cp_rccr = 0; | ||
51 | |||
52 | iip = (iic_t *)&cp->cp_dparam[PROFF_IIC]; | ||
53 | i2c = (i2c8xx_t *)&(immap->im_i2c); | ||
54 | |||
55 | /* Initialize Port B IIC pins. | ||
56 | */ | ||
57 | cp->cp_pbpar |= 0x00000030; | ||
58 | cp->cp_pbdir |= 0x00000030; | ||
59 | cp->cp_pbodr |= 0x00000030; | ||
60 | |||
61 | /* Initialize the parameter ram. | ||
62 | */ | ||
63 | |||
64 | /* Allocate space for a two transmit and one receive buffer | ||
65 | * descriptor in the DP ram. | ||
66 | * For now, this address seems OK, but it may have to | ||
67 | * change with newer versions of the firmware. | ||
68 | */ | ||
69 | dpaddr = 0x0840; | ||
70 | |||
71 | /* Set up the IIC parameters in the parameter ram. | ||
72 | */ | ||
73 | iip->iic_tbase = dpaddr; | ||
74 | iip->iic_rbase = dpaddr + (2 * sizeof(cbd_t)); | ||
75 | |||
76 | iip->iic_tfcr = SMC_EB; | ||
77 | iip->iic_rfcr = SMC_EB; | ||
78 | |||
79 | /* This should really be done by the reader/writer. | ||
80 | */ | ||
81 | iip->iic_mrblr = 128; | ||
82 | |||
83 | /* Initialize Tx/Rx parameters. | ||
84 | */ | ||
85 | cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG; | ||
86 | while (cp->cp_cpcr & CPM_CR_FLG); | ||
87 | |||
88 | /* Select an arbitrary address. Just make sure it is unique. | ||
89 | */ | ||
90 | i2c->i2c_i2add = 0x34; | ||
91 | |||
92 | /* Make clock run maximum slow. | ||
93 | */ | ||
94 | i2c->i2c_i2brg = 7; | ||
95 | |||
96 | /* Disable interrupts. | ||
97 | */ | ||
98 | i2c->i2c_i2cmr = 0; | ||
99 | i2c->i2c_i2cer = 0xff; | ||
100 | |||
101 | /* Enable SDMA. | ||
102 | */ | ||
103 | immap->im_siu_conf.sc_sdcr = 1; | ||
104 | |||
105 | iic_init_done = 1; | ||
106 | } | ||
107 | |||
108 | /* Read from IIC. | ||
109 | * Caller provides device address, memory buffer, and byte count. | ||
110 | */ | ||
111 | static u_char iitemp[32]; | ||
112 | |||
113 | void | ||
114 | iic_read(uint devaddr, u_char *buf, uint offset, uint count) | ||
115 | { | ||
116 | volatile iic_t *iip; | ||
117 | volatile i2c8xx_t *i2c; | ||
118 | volatile cbd_t *tbdf, *rbdf; | ||
119 | volatile cpm8xx_t *cp; | ||
120 | volatile immap_t *immap; | ||
121 | u_char *tb; | ||
122 | uint temp; | ||
123 | |||
124 | /* If the interface has not been initialized, do that now. | ||
125 | */ | ||
126 | if (!iic_init_done) | ||
127 | iic_init(); | ||
128 | |||
129 | immap = (immap_t *)IMAP_ADDR; | ||
130 | cp = (cpm8xx_t *)&(immap->im_cpm); | ||
131 | |||
132 | iip = (iic_t *)&cp->cp_dparam[PROFF_IIC]; | ||
133 | i2c = (i2c8xx_t *)&(immap->im_i2c); | ||
134 | |||
135 | tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase]; | ||
136 | rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase]; | ||
137 | |||
138 | /* Send a "dummy write" operation. This is a write request with | ||
139 | * only the offset sent, followed by another start condition. | ||
140 | * This will ensure we start reading from the first location | ||
141 | * of the EEPROM. | ||
142 | */ | ||
143 | tb = iitemp; | ||
144 | tb = (u_char *)(((uint)tb + 15) & ~15); | ||
145 | tbdf->cbd_bufaddr = (int)tb; | ||
146 | *tb = devaddr & 0xfe; /* Device address */ | ||
147 | *(tb+1) = offset; /* Offset */ | ||
148 | tbdf->cbd_datlen = 2; /* Length */ | ||
149 | tbdf->cbd_sc = | ||
150 | BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START; | ||
151 | |||
152 | i2c->i2c_i2mod = 1; /* Enable */ | ||
153 | i2c->i2c_i2cer = 0xff; | ||
154 | i2c->i2c_i2com = 0x81; /* Start master */ | ||
155 | |||
156 | /* Wait for IIC transfer. | ||
157 | */ | ||
158 | #if 0 | ||
159 | while ((i2c->i2c_i2cer & 3) == 0); | ||
160 | |||
161 | if (tbdf->cbd_sc & BD_SC_READY) | ||
162 | printf("IIC ra complete but tbuf ready\n"); | ||
163 | #else | ||
164 | temp = 10000000; | ||
165 | while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0)) | ||
166 | temp--; | ||
167 | #if 0 | ||
168 | /* We can't do this...there is no serial port yet! | ||
169 | */ | ||
170 | if (temp == 0) { | ||
171 | printf("Timeout reading EEPROM\n"); | ||
172 | return; | ||
173 | } | ||
174 | #endif | ||
175 | #endif | ||
176 | |||
177 | /* Chip errata, clear enable. | ||
178 | */ | ||
179 | i2c->i2c_i2mod = 0; | ||
180 | |||
181 | /* To read, we need an empty buffer of the proper length. | ||
182 | * All that is used is the first byte for address, the remainder | ||
183 | * is just used for timing (and doesn't really have to exist). | ||
184 | */ | ||
185 | tbdf->cbd_bufaddr = (int)tb; | ||
186 | *tb = devaddr | 1; /* Device address */ | ||
187 | rbdf->cbd_bufaddr = (uint)buf; /* Desination buffer */ | ||
188 | tbdf->cbd_datlen = rbdf->cbd_datlen = count + 1; /* Length */ | ||
189 | tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START; | ||
190 | rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP; | ||
191 | |||
192 | /* Chip bug, set enable here. | ||
193 | */ | ||
194 | i2c->i2c_i2mod = 1; /* Enable */ | ||
195 | i2c->i2c_i2cer = 0xff; | ||
196 | i2c->i2c_i2com = 0x81; /* Start master */ | ||
197 | |||
198 | /* Wait for IIC transfer. | ||
199 | */ | ||
200 | #if 0 | ||
201 | while ((i2c->i2c_i2cer & 1) == 0); | ||
202 | |||
203 | if (rbdf->cbd_sc & BD_SC_EMPTY) | ||
204 | printf("IIC read complete but rbuf empty\n"); | ||
205 | #else | ||
206 | temp = 10000000; | ||
207 | while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0)) | ||
208 | temp--; | ||
209 | #endif | ||
210 | |||
211 | /* Chip errata, clear enable. | ||
212 | */ | ||
213 | i2c->i2c_i2mod = 0; | ||
214 | } | ||
diff --git a/arch/ppc/boot/simple/m8260_tty.c b/arch/ppc/boot/simple/m8260_tty.c new file mode 100644 index 000000000000..d770947e9b8f --- /dev/null +++ b/arch/ppc/boot/simple/m8260_tty.c | |||
@@ -0,0 +1,325 @@ | |||
1 | /* Minimal serial functions needed to send messages out the serial | ||
2 | * port on SMC1. | ||
3 | */ | ||
4 | #include <linux/types.h> | ||
5 | #include <asm/mpc8260.h> | ||
6 | #include <asm/cpm2.h> | ||
7 | #include <asm/immap_cpm2.h> | ||
8 | |||
9 | uint no_print; | ||
10 | extern char *params[]; | ||
11 | extern int nparams; | ||
12 | static u_char cons_hold[128], *sgptr; | ||
13 | static int cons_hold_cnt; | ||
14 | |||
15 | /* If defined, enables serial console. The value (1 through 4) | ||
16 | * should designate which SCC is used, but this isn't complete. Only | ||
17 | * SCC1 is known to work at this time. | ||
18 | * We're only linked if SERIAL_CPM_CONSOLE=y, so we only need to test | ||
19 | * SERIAL_CPM_SCC1. | ||
20 | */ | ||
21 | #ifdef CONFIG_SERIAL_CPM_SCC1 | ||
22 | #define SCC_CONSOLE 1 | ||
23 | #endif | ||
24 | |||
25 | unsigned long | ||
26 | serial_init(int ignored, bd_t *bd) | ||
27 | { | ||
28 | #ifdef SCC_CONSOLE | ||
29 | volatile scc_t *sccp; | ||
30 | volatile scc_uart_t *sup; | ||
31 | #else | ||
32 | volatile smc_t *sp; | ||
33 | volatile smc_uart_t *up; | ||
34 | #endif | ||
35 | volatile cbd_t *tbdf, *rbdf; | ||
36 | volatile cpm2_map_t *ip; | ||
37 | volatile iop_cpm2_t *io; | ||
38 | volatile cpm_cpm2_t *cp; | ||
39 | uint dpaddr, memaddr; | ||
40 | |||
41 | ip = (cpm2_map_t *)CPM_MAP_ADDR; | ||
42 | cp = &ip->im_cpm; | ||
43 | io = &ip->im_ioport; | ||
44 | |||
45 | /* Perform a reset. | ||
46 | */ | ||
47 | cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG); | ||
48 | |||
49 | /* Wait for it. | ||
50 | */ | ||
51 | while (cp->cp_cpcr & CPM_CR_FLG); | ||
52 | |||
53 | #ifdef CONFIG_ADS8260 | ||
54 | /* Enable the RS-232 transceivers. | ||
55 | */ | ||
56 | *(volatile uint *)(BCSR_ADDR + 4) &= | ||
57 | ~(BCSR1_RS232_EN1 | BCSR1_RS232_EN2); | ||
58 | #endif | ||
59 | |||
60 | #ifdef SCC_CONSOLE | ||
61 | sccp = (scc_t *)&(ip->im_scc[SCC_CONSOLE-1]); | ||
62 | sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; | ||
63 | sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); | ||
64 | sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | ||
65 | |||
66 | /* Use Port D for SCC1 instead of other functions. | ||
67 | */ | ||
68 | io->iop_ppard |= 0x00000003; | ||
69 | io->iop_psord &= ~0x00000001; /* Rx */ | ||
70 | io->iop_psord |= 0x00000002; /* Tx */ | ||
71 | io->iop_pdird &= ~0x00000001; /* Rx */ | ||
72 | io->iop_pdird |= 0x00000002; /* Tx */ | ||
73 | |||
74 | #else | ||
75 | sp = (smc_t*)&(ip->im_smc[0]); | ||
76 | *(ushort *)(&ip->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1; | ||
77 | up = (smc_uart_t *)&ip->im_dprambase[PROFF_SMC1]; | ||
78 | |||
79 | /* Disable transmitter/receiver. | ||
80 | */ | ||
81 | sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); | ||
82 | |||
83 | /* Use Port D for SMC1 instead of other functions. | ||
84 | */ | ||
85 | io->iop_ppard |= 0x00c00000; | ||
86 | io->iop_pdird |= 0x00400000; | ||
87 | io->iop_pdird &= ~0x00800000; | ||
88 | io->iop_psord &= ~0x00c00000; | ||
89 | #endif | ||
90 | |||
91 | /* Allocate space for two buffer descriptors in the DP ram. | ||
92 | * For now, this address seems OK, but it may have to | ||
93 | * change with newer versions of the firmware. | ||
94 | */ | ||
95 | dpaddr = 0x0800; | ||
96 | |||
97 | /* Grab a few bytes from the top of memory. | ||
98 | */ | ||
99 | memaddr = (bd->bi_memsize - 256) & ~15; | ||
100 | |||
101 | /* Set the physical address of the host memory buffers in | ||
102 | * the buffer descriptors. | ||
103 | */ | ||
104 | rbdf = (cbd_t *)&ip->im_dprambase[dpaddr]; | ||
105 | rbdf->cbd_bufaddr = memaddr; | ||
106 | rbdf->cbd_sc = 0; | ||
107 | tbdf = rbdf + 1; | ||
108 | tbdf->cbd_bufaddr = memaddr+128; | ||
109 | tbdf->cbd_sc = 0; | ||
110 | |||
111 | /* Set up the uart parameters in the parameter ram. | ||
112 | */ | ||
113 | #ifdef SCC_CONSOLE | ||
114 | sup->scc_genscc.scc_rbase = dpaddr; | ||
115 | sup->scc_genscc.scc_tbase = dpaddr + sizeof(cbd_t); | ||
116 | |||
117 | /* Set up the uart parameters in the | ||
118 | * parameter ram. | ||
119 | */ | ||
120 | sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; | ||
121 | sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB; | ||
122 | |||
123 | sup->scc_genscc.scc_mrblr = 128; | ||
124 | sup->scc_maxidl = 8; | ||
125 | sup->scc_brkcr = 1; | ||
126 | sup->scc_parec = 0; | ||
127 | sup->scc_frmec = 0; | ||
128 | sup->scc_nosec = 0; | ||
129 | sup->scc_brkec = 0; | ||
130 | sup->scc_uaddr1 = 0; | ||
131 | sup->scc_uaddr2 = 0; | ||
132 | sup->scc_toseq = 0; | ||
133 | sup->scc_char1 = 0x8000; | ||
134 | sup->scc_char2 = 0x8000; | ||
135 | sup->scc_char3 = 0x8000; | ||
136 | sup->scc_char4 = 0x8000; | ||
137 | sup->scc_char5 = 0x8000; | ||
138 | sup->scc_char6 = 0x8000; | ||
139 | sup->scc_char7 = 0x8000; | ||
140 | sup->scc_char8 = 0x8000; | ||
141 | sup->scc_rccm = 0xc0ff; | ||
142 | |||
143 | /* Send the CPM an initialize command. | ||
144 | */ | ||
145 | cp->cp_cpcr = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0, | ||
146 | CPM_CR_INIT_TRX) | CPM_CR_FLG; | ||
147 | while (cp->cp_cpcr & CPM_CR_FLG); | ||
148 | |||
149 | /* Set UART mode, 8 bit, no parity, one stop. | ||
150 | * Enable receive and transmit. | ||
151 | */ | ||
152 | sccp->scc_gsmrh = 0; | ||
153 | sccp->scc_gsmrl = | ||
154 | (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); | ||
155 | |||
156 | /* Disable all interrupts and clear all pending | ||
157 | * events. | ||
158 | */ | ||
159 | sccp->scc_sccm = 0; | ||
160 | sccp->scc_scce = 0xffff; | ||
161 | sccp->scc_dsr = 0x7e7e; | ||
162 | sccp->scc_psmr = 0x3000; | ||
163 | |||
164 | /* Wire BRG1 to SCC1. The console driver will take care of | ||
165 | * others. | ||
166 | */ | ||
167 | ip->im_cpmux.cmx_scr = 0; | ||
168 | #else | ||
169 | up->smc_rbase = dpaddr; | ||
170 | up->smc_tbase = dpaddr+sizeof(cbd_t); | ||
171 | up->smc_rfcr = CPMFCR_EB; | ||
172 | up->smc_tfcr = CPMFCR_EB; | ||
173 | up->smc_brklen = 0; | ||
174 | up->smc_brkec = 0; | ||
175 | up->smc_brkcr = 0; | ||
176 | up->smc_mrblr = 128; | ||
177 | up->smc_maxidl = 8; | ||
178 | |||
179 | /* Set UART mode, 8 bit, no parity, one stop. | ||
180 | * Enable receive and transmit. | ||
181 | */ | ||
182 | sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; | ||
183 | |||
184 | /* Mask all interrupts and remove anything pending. | ||
185 | */ | ||
186 | sp->smc_smcm = 0; | ||
187 | sp->smc_smce = 0xff; | ||
188 | |||
189 | /* Set up the baud rate generator. | ||
190 | */ | ||
191 | ip->im_cpmux.cmx_smr = 0; | ||
192 | #endif | ||
193 | |||
194 | /* The baud rate divisor needs to be coordinated with clk_8260(). | ||
195 | */ | ||
196 | ip->im_brgc1 = | ||
197 | (((bd->bi_brgfreq/16) / bd->bi_baudrate) << 1) | | ||
198 | CPM_BRG_EN; | ||
199 | |||
200 | /* Make the first buffer the only buffer. | ||
201 | */ | ||
202 | tbdf->cbd_sc |= BD_SC_WRAP; | ||
203 | rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; | ||
204 | |||
205 | /* Initialize Tx/Rx parameters. | ||
206 | */ | ||
207 | #ifdef SCC_CONSOLE | ||
208 | sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); | ||
209 | #else | ||
210 | cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; | ||
211 | while (cp->cp_cpcr & CPM_CR_FLG); | ||
212 | |||
213 | /* Enable transmitter/receiver. | ||
214 | */ | ||
215 | sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; | ||
216 | #endif | ||
217 | |||
218 | /* This is ignored. | ||
219 | */ | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | int | ||
224 | serial_readbuf(u_char *cbuf) | ||
225 | { | ||
226 | volatile cbd_t *rbdf; | ||
227 | volatile char *buf; | ||
228 | #ifdef SCC_CONSOLE | ||
229 | volatile scc_uart_t *sup; | ||
230 | #else | ||
231 | volatile smc_uart_t *up; | ||
232 | #endif | ||
233 | volatile cpm2_map_t *ip; | ||
234 | int i, nc; | ||
235 | |||
236 | ip = (cpm2_map_t *)CPM_MAP_ADDR; | ||
237 | |||
238 | #ifdef SCC_CONSOLE | ||
239 | sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; | ||
240 | rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase]; | ||
241 | #else | ||
242 | up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); | ||
243 | rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase]; | ||
244 | #endif | ||
245 | |||
246 | /* Wait for character to show up. | ||
247 | */ | ||
248 | buf = (char *)rbdf->cbd_bufaddr; | ||
249 | while (rbdf->cbd_sc & BD_SC_EMPTY); | ||
250 | nc = rbdf->cbd_datlen; | ||
251 | for (i=0; i<nc; i++) | ||
252 | *cbuf++ = *buf++; | ||
253 | rbdf->cbd_sc |= BD_SC_EMPTY; | ||
254 | |||
255 | return(nc); | ||
256 | } | ||
257 | |||
258 | void | ||
259 | serial_putc(void *ignored, const char c) | ||
260 | { | ||
261 | volatile cbd_t *tbdf; | ||
262 | volatile char *buf; | ||
263 | #ifdef SCC_CONSOLE | ||
264 | volatile scc_uart_t *sup; | ||
265 | #else | ||
266 | volatile smc_uart_t *up; | ||
267 | #endif | ||
268 | volatile cpm2_map_t *ip; | ||
269 | |||
270 | ip = (cpm2_map_t *)CPM_MAP_ADDR; | ||
271 | #ifdef SCC_CONSOLE | ||
272 | sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; | ||
273 | tbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_tbase]; | ||
274 | #else | ||
275 | up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); | ||
276 | tbdf = (cbd_t *)&ip->im_dprambase[up->smc_tbase]; | ||
277 | #endif | ||
278 | |||
279 | /* Wait for last character to go. | ||
280 | */ | ||
281 | buf = (char *)tbdf->cbd_bufaddr; | ||
282 | while (tbdf->cbd_sc & BD_SC_READY); | ||
283 | |||
284 | *buf = c; | ||
285 | tbdf->cbd_datlen = 1; | ||
286 | tbdf->cbd_sc |= BD_SC_READY; | ||
287 | } | ||
288 | |||
289 | char | ||
290 | serial_getc(void *ignored) | ||
291 | { | ||
292 | char c; | ||
293 | |||
294 | if (cons_hold_cnt <= 0) { | ||
295 | cons_hold_cnt = serial_readbuf(cons_hold); | ||
296 | sgptr = cons_hold; | ||
297 | } | ||
298 | c = *sgptr++; | ||
299 | cons_hold_cnt--; | ||
300 | |||
301 | return(c); | ||
302 | } | ||
303 | |||
304 | int | ||
305 | serial_tstc(void *ignored) | ||
306 | { | ||
307 | volatile cbd_t *rbdf; | ||
308 | #ifdef SCC_CONSOLE | ||
309 | volatile scc_uart_t *sup; | ||
310 | #else | ||
311 | volatile smc_uart_t *up; | ||
312 | #endif | ||
313 | volatile cpm2_map_t *ip; | ||
314 | |||
315 | ip = (cpm2_map_t *)CPM_MAP_ADDR; | ||
316 | #ifdef SCC_CONSOLE | ||
317 | sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; | ||
318 | rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase]; | ||
319 | #else | ||
320 | up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); | ||
321 | rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase]; | ||
322 | #endif | ||
323 | |||
324 | return(!(rbdf->cbd_sc & BD_SC_EMPTY)); | ||
325 | } | ||
diff --git a/arch/ppc/boot/simple/m8xx_tty.c b/arch/ppc/boot/simple/m8xx_tty.c new file mode 100644 index 000000000000..1d2778e248c6 --- /dev/null +++ b/arch/ppc/boot/simple/m8xx_tty.c | |||
@@ -0,0 +1,290 @@ | |||
1 | /* Minimal serial functions needed to send messages out the serial | ||
2 | * port on the MBX console. | ||
3 | * | ||
4 | * The MBX uxes SMC1 for the serial port. We reset the port and use | ||
5 | * only the first BD that EPPC-Bug set up as a character FIFO. | ||
6 | * | ||
7 | * Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug | ||
8 | * use COM1 instead of SMC1 as the console port. This kinda sucks | ||
9 | * for the rest of the kernel, so here we force the use of SMC1 again. | ||
10 | */ | ||
11 | #include <linux/config.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <asm/uaccess.h> | ||
14 | #include <asm/mpc8xx.h> | ||
15 | #include <asm/commproc.h> | ||
16 | |||
17 | #ifdef CONFIG_MBX | ||
18 | #define MBX_CSR1 ((volatile u_char *)0xfa100000) | ||
19 | #define CSR1_COMEN (u_char)0x02 | ||
20 | #endif | ||
21 | |||
22 | #ifdef TQM_SMC2_CONSOLE | ||
23 | #define PROFF_CONS PROFF_SMC2 | ||
24 | #define CPM_CR_CH_CONS CPM_CR_CH_SMC2 | ||
25 | #define SMC_INDEX 1 | ||
26 | static volatile iop8xx_t *iopp = (iop8xx_t *)&(((immap_t *)IMAP_ADDR)->im_ioport); | ||
27 | #else | ||
28 | #define PROFF_CONS PROFF_SMC1 | ||
29 | #define CPM_CR_CH_CONS CPM_CR_CH_SMC1 | ||
30 | #define SMC_INDEX 0 | ||
31 | #endif | ||
32 | |||
33 | static cpm8xx_t *cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); | ||
34 | |||
35 | unsigned long | ||
36 | serial_init(int ignored, bd_t *bd) | ||
37 | { | ||
38 | volatile smc_t *sp; | ||
39 | volatile smc_uart_t *up; | ||
40 | volatile cbd_t *tbdf, *rbdf; | ||
41 | volatile cpm8xx_t *cp; | ||
42 | uint dpaddr, memaddr; | ||
43 | #ifndef CONFIG_MBX | ||
44 | uint ui; | ||
45 | #endif | ||
46 | |||
47 | cp = cpmp; | ||
48 | sp = (smc_t*)&(cp->cp_smc[SMC_INDEX]); | ||
49 | up = (smc_uart_t *)&cp->cp_dparam[PROFF_CONS]; | ||
50 | |||
51 | /* Disable transmitter/receiver. | ||
52 | */ | ||
53 | sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); | ||
54 | |||
55 | #ifdef CONFIG_FADS | ||
56 | /* Enable SMC1/2 transceivers. | ||
57 | */ | ||
58 | *((volatile uint *)BCSR1) &= ~(BCSR1_RS232EN_1|BCSR1_RS232EN_2); | ||
59 | #endif | ||
60 | |||
61 | #ifndef CONFIG_MBX | ||
62 | { | ||
63 | /* Initialize SMCx and use it for the console port. | ||
64 | */ | ||
65 | |||
66 | /* Enable SDMA. | ||
67 | */ | ||
68 | ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; | ||
69 | |||
70 | #ifdef TQM_SMC2_CONSOLE | ||
71 | /* Use Port A for SMC2 instead of other functions. | ||
72 | */ | ||
73 | iopp->iop_papar |= 0x00c0; | ||
74 | iopp->iop_padir &= ~0x00c0; | ||
75 | iopp->iop_paodr &= ~0x00c0; | ||
76 | #else | ||
77 | /* Use Port B for SMCs instead of other functions. | ||
78 | */ | ||
79 | cp->cp_pbpar |= 0x00000cc0; | ||
80 | cp->cp_pbdir &= ~0x00000cc0; | ||
81 | cp->cp_pbodr &= ~0x00000cc0; | ||
82 | #endif | ||
83 | |||
84 | /* Allocate space for two buffer descriptors in the DP ram. | ||
85 | * For now, this address seems OK, but it may have to | ||
86 | * change with newer versions of the firmware. | ||
87 | */ | ||
88 | dpaddr = 0x0800; | ||
89 | |||
90 | /* Grab a few bytes from the top of memory for SMC FIFOs. | ||
91 | */ | ||
92 | memaddr = (bd->bi_memsize - 32) & ~15; | ||
93 | |||
94 | /* Set the physical address of the host memory buffers in | ||
95 | * the buffer descriptors. | ||
96 | */ | ||
97 | rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; | ||
98 | rbdf->cbd_bufaddr = memaddr; | ||
99 | rbdf->cbd_sc = 0; | ||
100 | tbdf = rbdf + 1; | ||
101 | tbdf->cbd_bufaddr = memaddr+4; | ||
102 | tbdf->cbd_sc = 0; | ||
103 | |||
104 | /* Set up the uart parameters in the parameter ram. | ||
105 | */ | ||
106 | up->smc_rbase = dpaddr; | ||
107 | up->smc_tbase = dpaddr+sizeof(cbd_t); | ||
108 | up->smc_rfcr = SMC_EB; | ||
109 | up->smc_tfcr = SMC_EB; | ||
110 | |||
111 | /* Set UART mode, 8 bit, no parity, one stop. | ||
112 | * Enable receive and transmit. | ||
113 | */ | ||
114 | sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; | ||
115 | |||
116 | /* Mask all interrupts and remove anything pending. | ||
117 | */ | ||
118 | sp->smc_smcm = 0; | ||
119 | sp->smc_smce = 0xff; | ||
120 | |||
121 | /* Set up the baud rate generator. | ||
122 | * See 8xx_io/commproc.c for details. | ||
123 | * This wires BRG1 to SMC1 and BRG2 to SMC2; | ||
124 | */ | ||
125 | cp->cp_simode = 0x10000000; | ||
126 | ui = bd->bi_intfreq / 16 / bd->bi_baudrate; | ||
127 | #ifdef TQM_SMC2_CONSOLE | ||
128 | cp->cp_brgc2 = | ||
129 | #else | ||
130 | cp->cp_brgc1 = | ||
131 | #endif | ||
132 | ((ui - 1) < 4096) | ||
133 | ? (((ui - 1) << 1) | CPM_BRG_EN) | ||
134 | : ((((ui / 16) - 1) << 1) | CPM_BRG_EN | CPM_BRG_DIV16); | ||
135 | |||
136 | #else /* CONFIG_MBX */ | ||
137 | if (*MBX_CSR1 & CSR1_COMEN) { | ||
138 | /* COM1 is enabled. Initialize SMC1 and use it for | ||
139 | * the console port. | ||
140 | */ | ||
141 | |||
142 | /* Enable SDMA. | ||
143 | */ | ||
144 | ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; | ||
145 | |||
146 | /* Use Port B for SMCs instead of other functions. | ||
147 | */ | ||
148 | cp->cp_pbpar |= 0x00000cc0; | ||
149 | cp->cp_pbdir &= ~0x00000cc0; | ||
150 | cp->cp_pbodr &= ~0x00000cc0; | ||
151 | |||
152 | /* Allocate space for two buffer descriptors in the DP ram. | ||
153 | * For now, this address seems OK, but it may have to | ||
154 | * change with newer versions of the firmware. | ||
155 | */ | ||
156 | dpaddr = 0x0800; | ||
157 | |||
158 | /* Grab a few bytes from the top of memory. EPPC-Bug isn't | ||
159 | * running any more, so we can do this. | ||
160 | */ | ||
161 | memaddr = (bd->bi_memsize - 32) & ~15; | ||
162 | |||
163 | /* Set the physical address of the host memory buffers in | ||
164 | * the buffer descriptors. | ||
165 | */ | ||
166 | rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; | ||
167 | rbdf->cbd_bufaddr = memaddr; | ||
168 | rbdf->cbd_sc = 0; | ||
169 | tbdf = rbdf + 1; | ||
170 | tbdf->cbd_bufaddr = memaddr+4; | ||
171 | tbdf->cbd_sc = 0; | ||
172 | |||
173 | /* Set up the uart parameters in the parameter ram. | ||
174 | */ | ||
175 | up->smc_rbase = dpaddr; | ||
176 | up->smc_tbase = dpaddr+sizeof(cbd_t); | ||
177 | up->smc_rfcr = SMC_EB; | ||
178 | up->smc_tfcr = SMC_EB; | ||
179 | |||
180 | /* Set UART mode, 8 bit, no parity, one stop. | ||
181 | * Enable receive and transmit. | ||
182 | */ | ||
183 | sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; | ||
184 | |||
185 | /* Mask all interrupts and remove anything pending. | ||
186 | */ | ||
187 | sp->smc_smcm = 0; | ||
188 | sp->smc_smce = 0xff; | ||
189 | |||
190 | /* Set up the baud rate generator. | ||
191 | * See 8xx_io/commproc.c for details. | ||
192 | */ | ||
193 | cp->cp_simode = 0x10000000; | ||
194 | cp->cp_brgc1 = | ||
195 | (((bd->bi_intfreq/16) / 9600) << 1) | CPM_BRG_EN; | ||
196 | |||
197 | /* Enable SMC1 for console output. | ||
198 | */ | ||
199 | *MBX_CSR1 &= ~CSR1_COMEN; | ||
200 | } | ||
201 | else { | ||
202 | #endif /* ndef CONFIG_MBX */ | ||
203 | /* SMCx is used as console port. | ||
204 | */ | ||
205 | tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase]; | ||
206 | rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase]; | ||
207 | |||
208 | /* Issue a stop transmit, and wait for it. | ||
209 | */ | ||
210 | cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, | ||
211 | CPM_CR_STOP_TX) | CPM_CR_FLG; | ||
212 | while (cp->cp_cpcr & CPM_CR_FLG); | ||
213 | } | ||
214 | |||
215 | /* Make the first buffer the only buffer. | ||
216 | */ | ||
217 | tbdf->cbd_sc |= BD_SC_WRAP; | ||
218 | rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; | ||
219 | |||
220 | /* Single character receive. | ||
221 | */ | ||
222 | up->smc_mrblr = 1; | ||
223 | up->smc_maxidl = 0; | ||
224 | |||
225 | /* Initialize Tx/Rx parameters. | ||
226 | */ | ||
227 | cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_INIT_TRX) | CPM_CR_FLG; | ||
228 | while (cp->cp_cpcr & CPM_CR_FLG); | ||
229 | |||
230 | /* Enable transmitter/receiver. | ||
231 | */ | ||
232 | sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; | ||
233 | |||
234 | /* This is ignored. | ||
235 | */ | ||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | void | ||
240 | serial_putc(void *ignored, const char c) | ||
241 | { | ||
242 | volatile cbd_t *tbdf; | ||
243 | volatile char *buf; | ||
244 | volatile smc_uart_t *up; | ||
245 | |||
246 | up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; | ||
247 | tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase]; | ||
248 | |||
249 | /* Wait for last character to go. | ||
250 | */ | ||
251 | buf = (char *)tbdf->cbd_bufaddr; | ||
252 | while (tbdf->cbd_sc & BD_SC_READY); | ||
253 | |||
254 | *buf = c; | ||
255 | tbdf->cbd_datlen = 1; | ||
256 | tbdf->cbd_sc |= BD_SC_READY; | ||
257 | } | ||
258 | |||
259 | char | ||
260 | serial_getc(void *ignored) | ||
261 | { | ||
262 | volatile cbd_t *rbdf; | ||
263 | volatile char *buf; | ||
264 | volatile smc_uart_t *up; | ||
265 | char c; | ||
266 | |||
267 | up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; | ||
268 | rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; | ||
269 | |||
270 | /* Wait for character to show up. | ||
271 | */ | ||
272 | buf = (char *)rbdf->cbd_bufaddr; | ||
273 | while (rbdf->cbd_sc & BD_SC_EMPTY); | ||
274 | c = *buf; | ||
275 | rbdf->cbd_sc |= BD_SC_EMPTY; | ||
276 | |||
277 | return(c); | ||
278 | } | ||
279 | |||
280 | int | ||
281 | serial_tstc(void *ignored) | ||
282 | { | ||
283 | volatile cbd_t *rbdf; | ||
284 | volatile smc_uart_t *up; | ||
285 | |||
286 | up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; | ||
287 | rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; | ||
288 | |||
289 | return(!(rbdf->cbd_sc & BD_SC_EMPTY)); | ||
290 | } | ||
diff --git a/arch/ppc/boot/simple/misc-chestnut.c b/arch/ppc/boot/simple/misc-chestnut.c new file mode 100644 index 000000000000..0dce7f3557e4 --- /dev/null +++ b/arch/ppc/boot/simple/misc-chestnut.c | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/misc-chestnut.c | ||
3 | * | ||
4 | * Setup for the IBM Chestnut (ibm-750fxgx_eval) | ||
5 | * | ||
6 | * Author: Mark A. Greer <mgreer@mvista.com> | ||
7 | * | ||
8 | * 2005 (c) MontaVista Software, Inc. This file is licensed under | ||
9 | * the terms of the GNU General Public License version 2. This program | ||
10 | * is licensed "as is" without any warranty of any kind, whether express | ||
11 | * or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <asm/io.h> | ||
17 | #include <asm/mv64x60_defs.h> | ||
18 | #include <platforms/chestnut.h> | ||
19 | |||
20 | /* Not in the kernel so won't include kernel.h to get its 'max' definition */ | ||
21 | #define max(a,b) (((a) > (b)) ? (a) : (b)) | ||
22 | |||
23 | void | ||
24 | mv64x60_board_init(void __iomem *old_base, void __iomem *new_base) | ||
25 | { | ||
26 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
27 | /* | ||
28 | * Change device bus 2 window so that bootoader can do I/O thru | ||
29 | * 8250/16550 UART that's mapped in that window. | ||
30 | */ | ||
31 | out_le32(new_base + MV64x60_CPU2DEV_2_BASE, CHESTNUT_UART_BASE >> 16); | ||
32 | out_le32(new_base + MV64x60_CPU2DEV_2_SIZE, CHESTNUT_UART_SIZE >> 16); | ||
33 | __asm__ __volatile__("sync"); | ||
34 | #endif | ||
35 | } | ||
diff --git a/arch/ppc/boot/simple/misc-cpci690.c b/arch/ppc/boot/simple/misc-cpci690.c new file mode 100644 index 000000000000..ef08e86c9b25 --- /dev/null +++ b/arch/ppc/boot/simple/misc-cpci690.c | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/misc-cpci690.c | ||
3 | * | ||
4 | * Add birec data for Force CPCI690 board. | ||
5 | * | ||
6 | * Author: Mark A. Greer <source@mvista.com> | ||
7 | * | ||
8 | * 2003 (c) MontaVista Software, Inc. This file is licensed under | ||
9 | * the terms of the GNU General Public License version 2. This program | ||
10 | * is licensed "as is" without any warranty of any kind, whether express | ||
11 | * or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/types.h> | ||
15 | #include <platforms/cpci690.h> | ||
16 | |||
17 | extern u32 mv64x60_console_baud; | ||
18 | extern u32 mv64x60_mpsc_clk_src; | ||
19 | extern u32 mv64x60_mpsc_clk_freq; | ||
20 | |||
21 | void | ||
22 | mv64x60_board_init(void __iomem *old_base, void __iomem *new_base) | ||
23 | { | ||
24 | mv64x60_console_baud = CPCI690_MPSC_BAUD; | ||
25 | mv64x60_mpsc_clk_src = CPCI690_MPSC_CLK_SRC; | ||
26 | mv64x60_mpsc_clk_freq = CPCI690_BUS_FREQ; | ||
27 | } | ||
diff --git a/arch/ppc/boot/simple/misc-embedded.c b/arch/ppc/boot/simple/misc-embedded.c new file mode 100644 index 000000000000..3865f3f8dcd1 --- /dev/null +++ b/arch/ppc/boot/simple/misc-embedded.c | |||
@@ -0,0 +1,275 @@ | |||
1 | /* | ||
2 | * Originally adapted by Gary Thomas. Much additional work by | ||
3 | * Cort Dougan <cort@fsmlabs.com>. On top of that still more work by | ||
4 | * Dan Malek <dmalek@jlc.net>. | ||
5 | * | ||
6 | * Currently maintained by: Tom Rini <trini@kernel.crashing.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/config.h> | ||
10 | #include <linux/types.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <asm/bootinfo.h> | ||
13 | #include <asm/mmu.h> | ||
14 | #include <asm/page.h> | ||
15 | #include <asm/residual.h> | ||
16 | #if defined(CONFIG_4xx) | ||
17 | #include <asm/ibm4xx.h> | ||
18 | #elif defined(CONFIG_8xx) | ||
19 | #include <asm/mpc8xx.h> | ||
20 | #elif defined(CONFIG_8260) | ||
21 | #include <asm/mpc8260.h> | ||
22 | #endif | ||
23 | |||
24 | #include "nonstdio.h" | ||
25 | |||
26 | /* The linker tells us where the image is. */ | ||
27 | extern char __image_begin, __image_end; | ||
28 | extern char __ramdisk_begin, __ramdisk_end; | ||
29 | extern char _end[]; | ||
30 | |||
31 | /* Because of the limited amount of memory on embedded, it presents | ||
32 | * loading problems. The biggest is that we load this boot program | ||
33 | * into a relatively low memory address, and the Linux kernel Bss often | ||
34 | * extends into this space when it get loaded. When the kernel starts | ||
35 | * and zeros the BSS space, it also writes over the information we | ||
36 | * save here and pass to the kernel (usually board info). | ||
37 | * On these boards, we grab some known memory holes to hold this information. | ||
38 | */ | ||
39 | char cmd_buf[256]; | ||
40 | char *cmd_line = cmd_buf; | ||
41 | char *avail_ram; | ||
42 | char *end_avail; | ||
43 | char *zimage_start; | ||
44 | |||
45 | /* This is for 4xx treeboot. It provides a place for the bootrom | ||
46 | * give us a pointer to a rom environment command line. | ||
47 | */ | ||
48 | char *bootrom_cmdline = ""; | ||
49 | |||
50 | /* This is the default cmdline that will be given to the user at boot time.. | ||
51 | * If none was specified at compile time, we'll give it one that should work. | ||
52 | * -- Tom */ | ||
53 | #ifdef CONFIG_CMDLINE_BOOL | ||
54 | char compiled_string[] = CONFIG_CMDLINE; | ||
55 | #endif | ||
56 | char ramroot_string[] = "root=/dev/ram"; | ||
57 | char netroot_string[] = "root=/dev/nfs rw ip=on"; | ||
58 | |||
59 | /* Serial port to use. */ | ||
60 | unsigned long com_port; | ||
61 | |||
62 | /* We need to make sure that this is before the images to ensure | ||
63 | * that it's in a mapped location. - Tom */ | ||
64 | bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot"))); | ||
65 | bd_t *hold_residual = &hold_resid_buf; | ||
66 | |||
67 | extern unsigned long serial_init(int chan, bd_t *bp); | ||
68 | extern void serial_close(unsigned long com_port); | ||
69 | extern unsigned long start; | ||
70 | extern void flush_instruction_cache(void); | ||
71 | extern void gunzip(void *, int, unsigned char *, int *); | ||
72 | extern void embed_config(bd_t **bp); | ||
73 | |||
74 | /* Weak function for boards which don't need to build the | ||
75 | * board info struct because they are using PPCBoot/U-Boot. | ||
76 | */ | ||
77 | void __attribute__ ((weak)) | ||
78 | embed_config(bd_t **bdp) | ||
79 | { | ||
80 | } | ||
81 | |||
82 | unsigned long | ||
83 | load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *bp) | ||
84 | { | ||
85 | char *cp, ch; | ||
86 | int timer = 0, zimage_size; | ||
87 | unsigned long initrd_size; | ||
88 | |||
89 | /* First, capture the embedded board information. Then | ||
90 | * initialize the serial console port. | ||
91 | */ | ||
92 | embed_config(&bp); | ||
93 | #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) | ||
94 | com_port = serial_init(0, bp); | ||
95 | #endif | ||
96 | |||
97 | /* Grab some space for the command line and board info. Since | ||
98 | * we no longer use the ELF header, but it was loaded, grab | ||
99 | * that space. | ||
100 | */ | ||
101 | #ifdef CONFIG_MBX | ||
102 | /* Because of the way the MBX loads the ELF image, we can't | ||
103 | * tell where we started. We read a magic variable from the NVRAM | ||
104 | * that gives us the intermediate buffer load address. | ||
105 | */ | ||
106 | load_addr = *(uint *)0xfa000020; | ||
107 | load_addr += 0x10000; /* Skip ELF header */ | ||
108 | #endif | ||
109 | /* copy board data */ | ||
110 | if (bp) | ||
111 | memcpy(hold_residual,bp,sizeof(bd_t)); | ||
112 | |||
113 | /* Set end of memory available to us. It is always the highest | ||
114 | * memory address provided by the board information. | ||
115 | */ | ||
116 | end_avail = (char *)(bp->bi_memsize); | ||
117 | |||
118 | puts("\nloaded at: "); puthex(load_addr); | ||
119 | puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); | ||
120 | if ( (unsigned long)load_addr != (unsigned long)&start ) { | ||
121 | puts("relocated to: "); puthex((unsigned long)&start); | ||
122 | puts(" "); | ||
123 | puthex((unsigned long)((unsigned long)&start + (4*num_words))); | ||
124 | puts("\n"); | ||
125 | } | ||
126 | |||
127 | if ( bp ) { | ||
128 | puts("board data at: "); puthex((unsigned long)bp); | ||
129 | puts(" "); | ||
130 | puthex((unsigned long)((unsigned long)bp + sizeof(bd_t))); | ||
131 | puts("\nrelocated to: "); | ||
132 | puthex((unsigned long)hold_residual); | ||
133 | puts(" "); | ||
134 | puthex((unsigned long)((unsigned long)hold_residual + sizeof(bd_t))); | ||
135 | puts("\n"); | ||
136 | } | ||
137 | |||
138 | /* | ||
139 | * We link ourself to an arbitrary low address. When we run, we | ||
140 | * relocate outself to that address. __image_being points to | ||
141 | * the part of the image where the zImage is. -- Tom | ||
142 | */ | ||
143 | zimage_start = (char *)(unsigned long)(&__image_begin); | ||
144 | zimage_size = (unsigned long)(&__image_end) - | ||
145 | (unsigned long)(&__image_begin); | ||
146 | |||
147 | initrd_size = (unsigned long)(&__ramdisk_end) - | ||
148 | (unsigned long)(&__ramdisk_begin); | ||
149 | |||
150 | /* | ||
151 | * The zImage and initrd will be between start and _end, so they've | ||
152 | * already been moved once. We're good to go now. -- Tom | ||
153 | */ | ||
154 | puts("zimage at: "); puthex((unsigned long)zimage_start); | ||
155 | puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); | ||
156 | puts("\n"); | ||
157 | |||
158 | if ( initrd_size ) { | ||
159 | puts("initrd at: "); | ||
160 | puthex((unsigned long)(&__ramdisk_begin)); | ||
161 | puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n"); | ||
162 | } | ||
163 | |||
164 | /* | ||
165 | * setup avail_ram - this is the first part of ram usable | ||
166 | * by the uncompress code. Anything after this program in RAM | ||
167 | * is now fair game. -- Tom | ||
168 | */ | ||
169 | avail_ram = (char *)PAGE_ALIGN((unsigned long)_end); | ||
170 | |||
171 | puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" "); | ||
172 | puthex((unsigned long)end_avail); puts("\n"); | ||
173 | puts("\nLinux/PPC load: "); | ||
174 | cp = cmd_line; | ||
175 | /* This is where we try and pick the right command line for booting. | ||
176 | * If we were given one at compile time, use it. It Is Right. | ||
177 | * If we weren't, see if we have a ramdisk. If so, thats root. | ||
178 | * When in doubt, give them the netroot (root=/dev/nfs rw) -- Tom | ||
179 | */ | ||
180 | #ifdef CONFIG_CMDLINE_BOOL | ||
181 | memcpy (cmd_line, compiled_string, sizeof(compiled_string)); | ||
182 | #else | ||
183 | if ( initrd_size ) | ||
184 | memcpy (cmd_line, ramroot_string, sizeof(ramroot_string)); | ||
185 | else | ||
186 | memcpy (cmd_line, netroot_string, sizeof(netroot_string)); | ||
187 | #endif | ||
188 | while ( *cp ) | ||
189 | putc(*cp++); | ||
190 | while (timer++ < 5*1000) { | ||
191 | if (tstc()) { | ||
192 | while ((ch = getc()) != '\n' && ch != '\r') { | ||
193 | if (ch == '\b' || ch == '\177') { | ||
194 | if (cp != cmd_line) { | ||
195 | cp--; | ||
196 | puts("\b \b"); | ||
197 | } | ||
198 | } else if (ch == '\030' /* ^x */ | ||
199 | || ch == '\025') { /* ^u */ | ||
200 | while (cp != cmd_line) { | ||
201 | cp--; | ||
202 | puts("\b \b"); | ||
203 | } | ||
204 | } else { | ||
205 | *cp++ = ch; | ||
206 | putc(ch); | ||
207 | } | ||
208 | } | ||
209 | break; /* Exit 'timer' loop */ | ||
210 | } | ||
211 | udelay(1000); /* 1 msec */ | ||
212 | } | ||
213 | *cp = 0; | ||
214 | puts("\nUncompressing Linux..."); | ||
215 | |||
216 | gunzip(0, 0x400000, zimage_start, &zimage_size); | ||
217 | flush_instruction_cache(); | ||
218 | puts("done.\n"); | ||
219 | { | ||
220 | struct bi_record *rec; | ||
221 | unsigned long initrd_loc = 0; | ||
222 | unsigned long rec_loc = _ALIGN((unsigned long)(zimage_size) + | ||
223 | (1 << 20) - 1, (1 << 20)); | ||
224 | rec = (struct bi_record *)rec_loc; | ||
225 | |||
226 | /* We need to make sure that the initrd and bi_recs do not | ||
227 | * overlap. */ | ||
228 | if ( initrd_size ) { | ||
229 | initrd_loc = (unsigned long)(&__ramdisk_begin); | ||
230 | /* If the bi_recs are in the middle of the current | ||
231 | * initrd, move the initrd to the next MB | ||
232 | * boundary. */ | ||
233 | if ((rec_loc > initrd_loc) && | ||
234 | ((initrd_loc + initrd_size) | ||
235 | > rec_loc)) { | ||
236 | initrd_loc = _ALIGN((unsigned long)(zimage_size) | ||
237 | + (2 << 20) - 1, (2 << 20)); | ||
238 | memmove((void *)initrd_loc, &__ramdisk_begin, | ||
239 | initrd_size); | ||
240 | puts("initrd moved: "); puthex(initrd_loc); | ||
241 | puts(" "); puthex(initrd_loc + initrd_size); | ||
242 | puts("\n"); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | rec->tag = BI_FIRST; | ||
247 | rec->size = sizeof(struct bi_record); | ||
248 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
249 | |||
250 | rec->tag = BI_CMD_LINE; | ||
251 | memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1); | ||
252 | rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1; | ||
253 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
254 | |||
255 | if ( initrd_size ) { | ||
256 | rec->tag = BI_INITRD; | ||
257 | rec->data[0] = initrd_loc; | ||
258 | rec->data[1] = initrd_size; | ||
259 | rec->size = sizeof(struct bi_record) + 2 * | ||
260 | sizeof(unsigned long); | ||
261 | rec = (struct bi_record *)((unsigned long)rec + | ||
262 | rec->size); | ||
263 | } | ||
264 | |||
265 | rec->tag = BI_LAST; | ||
266 | rec->size = sizeof(struct bi_record); | ||
267 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
268 | } | ||
269 | puts("Now booting the kernel\n"); | ||
270 | #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) | ||
271 | serial_close(com_port); | ||
272 | #endif | ||
273 | |||
274 | return (unsigned long)hold_residual; | ||
275 | } | ||
diff --git a/arch/ppc/boot/simple/misc-ev64260.c b/arch/ppc/boot/simple/misc-ev64260.c new file mode 100644 index 000000000000..52ece6937a7a --- /dev/null +++ b/arch/ppc/boot/simple/misc-ev64260.c | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/misc-ev64260.c | ||
3 | * | ||
4 | * Host bridge init code for the Marvell/Galileo EV-64260-BP evaluation board | ||
5 | * with a GT64260 onboard. | ||
6 | * | ||
7 | * Author: Mark A. Greer <mgreer@mvista.com> | ||
8 | * | ||
9 | * 2001 (c) MontaVista Software, Inc. This file is licensed under | ||
10 | * the terms of the GNU General Public License version 2. This program | ||
11 | * is licensed "as is" without any warranty of any kind, whether express | ||
12 | * or implied. | ||
13 | */ | ||
14 | |||
15 | #include <linux/config.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <asm/reg.h> | ||
18 | #include <asm/io.h> | ||
19 | #include <asm/mv64x60_defs.h> | ||
20 | #include <platforms/ev64260.h> | ||
21 | |||
22 | #ifdef CONFIG_SERIAL_MPSC_CONSOLE | ||
23 | extern u32 mv64x60_console_baud; | ||
24 | extern u32 mv64x60_mpsc_clk_src; | ||
25 | extern u32 mv64x60_mpsc_clk_freq; | ||
26 | #endif | ||
27 | |||
28 | void | ||
29 | mv64x60_board_init(void __iomem *old_base, void __iomem *new_base) | ||
30 | { | ||
31 | u32 p, v; | ||
32 | |||
33 | /* DINK doesn't enable 745x timebase, so enable here (Adrian Cox) */ | ||
34 | p = mfspr(SPRN_PVR); | ||
35 | p >>= 16; | ||
36 | |||
37 | /* Reasonable SWAG at a 745x PVR value */ | ||
38 | if (((p & 0xfff0) == 0x8000) && (p != 0x800c)) { | ||
39 | v = mfspr(SPRN_HID0); | ||
40 | v |= HID0_TBEN; | ||
41 | mtspr(SPRN_HID0, v); | ||
42 | } | ||
43 | |||
44 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
45 | /* | ||
46 | * Change device bus 2 window so that bootoader can do I/O thru | ||
47 | * 8250/16550 UART that's mapped in that window. | ||
48 | */ | ||
49 | out_le32(new_base + MV64x60_CPU2DEV_2_BASE, EV64260_UART_BASE >> 20); | ||
50 | out_le32(new_base + MV64x60_CPU2DEV_2_SIZE, EV64260_UART_END >> 20); | ||
51 | __asm__ __volatile__("sync"); | ||
52 | #elif defined(CONFIG_SERIAL_MPSC_CONSOLE) | ||
53 | mv64x60_console_baud = EV64260_DEFAULT_BAUD; | ||
54 | mv64x60_mpsc_clk_src = EV64260_MPSC_CLK_SRC; | ||
55 | mv64x60_mpsc_clk_freq = EV64260_MPSC_CLK_FREQ; | ||
56 | #endif | ||
57 | } | ||
diff --git a/arch/ppc/boot/simple/misc-katana.c b/arch/ppc/boot/simple/misc-katana.c new file mode 100644 index 000000000000..b6e1bb833157 --- /dev/null +++ b/arch/ppc/boot/simple/misc-katana.c | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/misc-katana.c | ||
3 | * | ||
4 | * Set up MPSC values to bootwrapper can prompt user. | ||
5 | * | ||
6 | * Author: Mark A. Greer <source@mvista.com> | ||
7 | * | ||
8 | * 2004 (c) MontaVista Software, Inc. This file is licensed under | ||
9 | * the terms of the GNU General Public License version 2. This program | ||
10 | * is licensed "as is" without any warranty of any kind, whether express | ||
11 | * or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <asm/io.h> | ||
17 | #include <asm/mv64x60_defs.h> | ||
18 | #include <platforms/katana.h> | ||
19 | |||
20 | extern u32 mv64x60_console_baud; | ||
21 | extern u32 mv64x60_mpsc_clk_src; | ||
22 | extern u32 mv64x60_mpsc_clk_freq; | ||
23 | |||
24 | /* Not in the kernel so won't include kernel.h to get its 'min' definition */ | ||
25 | #ifndef min | ||
26 | #define min(a,b) (((a) < (b)) ? (a) : (b)) | ||
27 | #endif | ||
28 | |||
29 | void | ||
30 | mv64x60_board_init(void __iomem *old_base, void __iomem *new_base) | ||
31 | { | ||
32 | mv64x60_console_baud = KATANA_DEFAULT_BAUD; | ||
33 | mv64x60_mpsc_clk_src = KATANA_MPSC_CLK_SRC; | ||
34 | mv64x60_mpsc_clk_freq = | ||
35 | min(katana_bus_freq((void __iomem *)KATANA_CPLD_BASE), | ||
36 | MV64x60_TCLK_FREQ_MAX); | ||
37 | } | ||
diff --git a/arch/ppc/boot/simple/misc-mv64x60.c b/arch/ppc/boot/simple/misc-mv64x60.c new file mode 100644 index 000000000000..7e88fc6d207d --- /dev/null +++ b/arch/ppc/boot/simple/misc-mv64x60.c | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/misc-mv64x60.c | ||
3 | * | ||
4 | * Relocate bridge's register base and call board specific routine. | ||
5 | * | ||
6 | * Author: Mark A. Greer <source@mvista.com> | ||
7 | * | ||
8 | * 2005 (c) MontaVista Software, Inc. This file is licensed under | ||
9 | * the terms of the GNU General Public License version 2. This program | ||
10 | * is licensed "as is" without any warranty of any kind, whether express | ||
11 | * or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <asm/io.h> | ||
17 | #include <asm/mv64x60_defs.h> | ||
18 | |||
19 | extern struct bi_record *decompress_kernel(unsigned long load_addr, | ||
20 | int num_words, unsigned long cksum); | ||
21 | |||
22 | void | ||
23 | mv64x60_move_base(void __iomem *old_base, void __iomem *new_base) | ||
24 | { | ||
25 | u32 bits, mask, b; | ||
26 | |||
27 | if (old_base != new_base) { | ||
28 | #ifdef CONFIG_GT64260 | ||
29 | bits = 12; | ||
30 | mask = 0x07000000; | ||
31 | #else /* Must be mv64[34]60 */ | ||
32 | bits = 16; | ||
33 | mask = 0x03000000; | ||
34 | #endif | ||
35 | b = in_le32(old_base + MV64x60_INTERNAL_SPACE_DECODE); | ||
36 | b &= mask; | ||
37 | b |= ((u32)new_base >> (32 - bits)); | ||
38 | out_le32(old_base + MV64x60_INTERNAL_SPACE_DECODE, b); | ||
39 | |||
40 | __asm__ __volatile__("sync"); | ||
41 | |||
42 | /* Wait for change to happen (in accordance with the manual) */ | ||
43 | while (in_le32(new_base + MV64x60_INTERNAL_SPACE_DECODE) != b); | ||
44 | } | ||
45 | } | ||
46 | |||
47 | void __attribute__ ((weak)) | ||
48 | mv64x60_board_init(void __iomem *old_base, void __iomem *new_base) | ||
49 | { | ||
50 | } | ||
51 | |||
52 | void * | ||
53 | load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, | ||
54 | void *ign1, void *ign2) | ||
55 | { | ||
56 | mv64x60_move_base((void __iomem *)CONFIG_MV64X60_BASE, | ||
57 | (void __iomem *)CONFIG_MV64X60_NEW_BASE); | ||
58 | mv64x60_board_init((void __iomem *)CONFIG_MV64X60_BASE, | ||
59 | (void __iomem *)CONFIG_MV64X60_NEW_BASE); | ||
60 | return decompress_kernel(load_addr, num_words, cksum); | ||
61 | } | ||
diff --git a/arch/ppc/boot/simple/misc-prep.c b/arch/ppc/boot/simple/misc-prep.c new file mode 100644 index 000000000000..75380ac41669 --- /dev/null +++ b/arch/ppc/boot/simple/misc-prep.c | |||
@@ -0,0 +1,212 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/misc-prep.c | ||
3 | * | ||
4 | * Maintainer: Tom Rini <trini@kernel.crashing.org> | ||
5 | * | ||
6 | * In the past: Gary Thomas, Cort Dougan <cort@cs.nmt.edu> | ||
7 | */ | ||
8 | |||
9 | #include <linux/config.h> | ||
10 | #include <linux/pci_ids.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <asm/residual.h> | ||
13 | #include <asm/string.h> | ||
14 | #include <asm/byteorder.h> | ||
15 | #include "mpc10x.h" | ||
16 | #include "of1275.h" | ||
17 | #include "nonstdio.h" | ||
18 | |||
19 | extern int keyb_present; /* keyboard controller is present by default */ | ||
20 | RESIDUAL hold_resid_buf; | ||
21 | RESIDUAL *hold_residual = &hold_resid_buf; | ||
22 | static void *OFW_interface; /* Pointer to OF, if available. */ | ||
23 | |||
24 | #ifdef CONFIG_VGA_CONSOLE | ||
25 | char *vidmem = (char *)0xC00B8000; | ||
26 | int lines = 25, cols = 80; | ||
27 | int orig_x, orig_y = 24; | ||
28 | #endif /* CONFIG_VGA_CONSOLE */ | ||
29 | |||
30 | extern int CRT_tstc(void); | ||
31 | extern int vga_init(unsigned char *ISA_mem); | ||
32 | extern void gunzip(void *, int, unsigned char *, int *); | ||
33 | extern unsigned long serial_init(int chan, void *ignored); | ||
34 | extern void serial_fixups(void); | ||
35 | extern struct bi_record *decompress_kernel(unsigned long load_addr, | ||
36 | int num_words, unsigned long cksum); | ||
37 | extern void disable_6xx_mmu(void); | ||
38 | extern unsigned long mpc10x_get_mem_size(void); | ||
39 | |||
40 | static void | ||
41 | writel(unsigned int val, unsigned int address) | ||
42 | { | ||
43 | /* Ensure I/O operations complete */ | ||
44 | __asm__ volatile("eieio"); | ||
45 | *(unsigned int *)address = cpu_to_le32(val); | ||
46 | } | ||
47 | |||
48 | #define PCI_CFG_ADDR(dev,off) ((0x80<<24) | (dev<<8) | (off&0xfc)) | ||
49 | #define PCI_CFG_DATA(off) (MPC10X_MAPA_CNFG_DATA+(off&3)) | ||
50 | |||
51 | static void | ||
52 | pci_read_config_32(unsigned char devfn, | ||
53 | unsigned char offset, | ||
54 | unsigned int *val) | ||
55 | { | ||
56 | /* Ensure I/O operations complete */ | ||
57 | __asm__ volatile("eieio"); | ||
58 | *(unsigned int *)PCI_CFG_ADDR(devfn,offset) = | ||
59 | cpu_to_le32(MPC10X_MAPA_CNFG_ADDR); | ||
60 | /* Ensure I/O operations complete */ | ||
61 | __asm__ volatile("eieio"); | ||
62 | *val = le32_to_cpu(*(unsigned int *)PCI_CFG_DATA(offset)); | ||
63 | return; | ||
64 | } | ||
65 | |||
66 | #ifdef CONFIG_VGA_CONSOLE | ||
67 | void | ||
68 | scroll(void) | ||
69 | { | ||
70 | int i; | ||
71 | |||
72 | memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 ); | ||
73 | for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 ) | ||
74 | vidmem[i] = ' '; | ||
75 | } | ||
76 | #endif /* CONFIG_VGA_CONSOLE */ | ||
77 | |||
78 | unsigned long | ||
79 | load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, | ||
80 | RESIDUAL *residual, void *OFW) | ||
81 | { | ||
82 | int start_multi = 0; | ||
83 | unsigned int pci_viddid, pci_did, tulip_pci_base, tulip_base; | ||
84 | |||
85 | /* If we have Open Firmware, initialise it immediately */ | ||
86 | if (OFW) { | ||
87 | OFW_interface = OFW; | ||
88 | ofinit(OFW_interface); | ||
89 | } | ||
90 | |||
91 | board_isa_init(); | ||
92 | #if defined(CONFIG_VGA_CONSOLE) | ||
93 | vga_init((unsigned char *)0xC0000000); | ||
94 | #endif /* CONFIG_VGA_CONSOLE */ | ||
95 | |||
96 | if (residual) { | ||
97 | /* Is this Motorola PPCBug? */ | ||
98 | if ((1 & residual->VitalProductData.FirmwareSupports) && | ||
99 | (1 == residual->VitalProductData.FirmwareSupplier)) { | ||
100 | unsigned char base_mod; | ||
101 | unsigned char board_type = inb(0x801) & 0xF0; | ||
102 | |||
103 | /* | ||
104 | * Reset the onboard 21x4x Ethernet | ||
105 | * Motorola Ethernet is at IDSEL 14 (devfn 0x70) | ||
106 | */ | ||
107 | pci_read_config_32(0x70, 0x00, &pci_viddid); | ||
108 | pci_did = (pci_viddid & 0xffff0000) >> 16; | ||
109 | /* Be sure we've really found a 21x4x chip */ | ||
110 | if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_DEC) && | ||
111 | ((pci_did == PCI_DEVICE_ID_DEC_TULIP_FAST) || | ||
112 | (pci_did == PCI_DEVICE_ID_DEC_TULIP) || | ||
113 | (pci_did == PCI_DEVICE_ID_DEC_TULIP_PLUS) || | ||
114 | (pci_did == PCI_DEVICE_ID_DEC_21142))) { | ||
115 | pci_read_config_32(0x70, | ||
116 | 0x10, | ||
117 | &tulip_pci_base); | ||
118 | /* Get the physical base address */ | ||
119 | tulip_base = | ||
120 | (tulip_pci_base & ~0x03UL) + 0x80000000; | ||
121 | /* Strobe the 21x4x reset bit in CSR0 */ | ||
122 | writel(0x1, tulip_base); | ||
123 | } | ||
124 | |||
125 | /* If this is genesis 2 board then check for no | ||
126 | * keyboard controller and more than one processor. | ||
127 | */ | ||
128 | if (board_type == 0xe0) { | ||
129 | base_mod = inb(0x803); | ||
130 | /* if a MVME2300/2400 or a Sitka then no keyboard */ | ||
131 | if((base_mod == 0xFA) || (base_mod == 0xF9) || | ||
132 | (base_mod == 0xE1)) { | ||
133 | keyb_present = 0; /* no keyboard */ | ||
134 | } | ||
135 | } | ||
136 | /* If this is a multiprocessor system then | ||
137 | * park the other processor so that the | ||
138 | * kernel knows where to find them. | ||
139 | */ | ||
140 | if (residual->MaxNumCpus > 1) | ||
141 | start_multi = 1; | ||
142 | } | ||
143 | memcpy(hold_residual,residual,sizeof(RESIDUAL)); | ||
144 | } | ||
145 | |||
146 | /* Call decompress_kernel */ | ||
147 | decompress_kernel(load_addr, num_words, cksum); | ||
148 | |||
149 | if (start_multi) { | ||
150 | residual->VitalProductData.SmpIar = (unsigned long)0xc0; | ||
151 | residual->Cpus[1].CpuState = CPU_GOOD; | ||
152 | hold_residual->VitalProductData.Reserved5 = 0xdeadbeef; | ||
153 | } | ||
154 | |||
155 | /* Now go and clear out the BATs and ensure that our MSR is | ||
156 | * correct .*/ | ||
157 | disable_6xx_mmu(); | ||
158 | |||
159 | /* Make r3 be a pointer to the residual data. */ | ||
160 | return (unsigned long)hold_residual; | ||
161 | } | ||
162 | |||
163 | unsigned long | ||
164 | get_mem_size(void) | ||
165 | { | ||
166 | unsigned int pci_viddid, pci_did; | ||
167 | |||
168 | /* First, figure out what kind of host bridge we are on. If it's | ||
169 | * an MPC10x, we can ask it directly how much memory it has. | ||
170 | * Otherwise, see if the residual data has anything. This isn't | ||
171 | * the best way, but it can be the only way. If there's nothing, | ||
172 | * assume 32MB. -- Tom. | ||
173 | */ | ||
174 | /* See what our host bridge is. */ | ||
175 | pci_read_config_32(0x00, 0x00, &pci_viddid); | ||
176 | pci_did = (pci_viddid & 0xffff0000) >> 16; | ||
177 | /* See if we are on an MPC10x. */ | ||
178 | if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA) | ||
179 | && ((pci_did == PCI_DEVICE_ID_MOTOROLA_MPC105) | ||
180 | || (pci_did == PCI_DEVICE_ID_MOTOROLA_MPC106) | ||
181 | || (pci_did == PCI_DEVICE_ID_MOTOROLA_MPC107))) | ||
182 | return mpc10x_get_mem_size(); | ||
183 | /* If it's not, see if we have anything in the residual data. */ | ||
184 | else if (hold_residual && hold_residual->TotalMemory) | ||
185 | return hold_residual->TotalMemory; | ||
186 | else if (OFW_interface) { | ||
187 | /* | ||
188 | * This is a 'best guess' check. We want to make sure | ||
189 | * we don't try this on a PReP box without OF | ||
190 | * -- Cort | ||
191 | */ | ||
192 | while (OFW_interface) | ||
193 | { | ||
194 | phandle dev_handle; | ||
195 | int mem_info[2]; | ||
196 | |||
197 | /* get handle to memory description */ | ||
198 | if (!(dev_handle = finddevice("/memory@0"))) | ||
199 | break; | ||
200 | |||
201 | /* get the info */ | ||
202 | if (getprop(dev_handle, "reg", mem_info, | ||
203 | sizeof(mem_info)) != 8) | ||
204 | break; | ||
205 | |||
206 | return mem_info[1]; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | /* Fall back to hard-coding 32MB. */ | ||
211 | return 32*1024*1024; | ||
212 | } | ||
diff --git a/arch/ppc/boot/simple/misc-radstone_ppc7d.c b/arch/ppc/boot/simple/misc-radstone_ppc7d.c new file mode 100644 index 000000000000..569e0d4feeaf --- /dev/null +++ b/arch/ppc/boot/simple/misc-radstone_ppc7d.c | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/misc-radstone_ppc7d.c | ||
3 | * | ||
4 | * Misc data for Radstone PPC7D board. | ||
5 | * | ||
6 | * Author: James Chapman <jchapman@katalix.com> | ||
7 | */ | ||
8 | |||
9 | #include <linux/types.h> | ||
10 | #include <platforms/radstone_ppc7d.h> | ||
11 | |||
12 | #if defined(CONFIG_SERIAL_MPSC_CONSOLE) | ||
13 | extern u32 mv64x60_console_baud; | ||
14 | extern u32 mv64x60_mpsc_clk_src; | ||
15 | extern u32 mv64x60_mpsc_clk_freq; | ||
16 | #endif | ||
17 | |||
18 | void | ||
19 | mv64x60_board_init(void __iomem *old_base, void __iomem *new_base) | ||
20 | { | ||
21 | #if defined(CONFIG_SERIAL_MPSC_CONSOLE) | ||
22 | mv64x60_console_baud = PPC7D_DEFAULT_BAUD; | ||
23 | mv64x60_mpsc_clk_src = PPC7D_MPSC_CLK_SRC; | ||
24 | mv64x60_mpsc_clk_freq = PPC7D_MPSC_CLK_FREQ; | ||
25 | #endif | ||
26 | } | ||
diff --git a/arch/ppc/boot/simple/misc-spruce.c b/arch/ppc/boot/simple/misc-spruce.c new file mode 100644 index 000000000000..d012c39278fd --- /dev/null +++ b/arch/ppc/boot/simple/misc-spruce.c | |||
@@ -0,0 +1,274 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/spruce/misc.c | ||
3 | * | ||
4 | * Misc. bootloader code for IBM Spruce reference platform | ||
5 | * | ||
6 | * Authors: Johnnie Peters <jpeters@mvista.com> | ||
7 | * Matt Porter <mporter@mvista.com> | ||
8 | * | ||
9 | * Derived from arch/ppc/boot/prep/misc.c | ||
10 | * | ||
11 | * 2000-2001 (c) MontaVista, Software, Inc. This file is licensed under | ||
12 | * the terms of the GNU General Public License version 2. This program | ||
13 | * is licensed "as is" without any warranty of any kind, whether express | ||
14 | * or implied. | ||
15 | */ | ||
16 | |||
17 | #include <linux/types.h> | ||
18 | #include <linux/config.h> | ||
19 | #include <linux/pci.h> | ||
20 | |||
21 | #include <asm/bootinfo.h> | ||
22 | |||
23 | extern unsigned long decompress_kernel(unsigned long load_addr, int num_words, | ||
24 | unsigned long cksum); | ||
25 | |||
26 | /* Define some important locations of the Spruce. */ | ||
27 | #define SPRUCE_PCI_CONFIG_ADDR 0xfec00000 | ||
28 | #define SPRUCE_PCI_CONFIG_DATA 0xfec00004 | ||
29 | |||
30 | /* PCI configuration space access routines. */ | ||
31 | unsigned int *pci_config_address = (unsigned int *)SPRUCE_PCI_CONFIG_ADDR; | ||
32 | unsigned char *pci_config_data = (unsigned char *)SPRUCE_PCI_CONFIG_DATA; | ||
33 | |||
34 | void cpc700_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, | ||
35 | unsigned char offset, unsigned char *val) | ||
36 | { | ||
37 | out_le32(pci_config_address, | ||
38 | (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); | ||
39 | |||
40 | *val= (in_le32((unsigned *)pci_config_data) >> (8 * (offset & 3))) & 0xff; | ||
41 | } | ||
42 | |||
43 | void cpc700_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, | ||
44 | unsigned char offset, unsigned char val) | ||
45 | { | ||
46 | out_le32(pci_config_address, | ||
47 | (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); | ||
48 | |||
49 | out_8(pci_config_data + (offset&3), val); | ||
50 | } | ||
51 | |||
52 | void cpc700_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, | ||
53 | unsigned char offset, unsigned short *val) | ||
54 | { | ||
55 | out_le32(pci_config_address, | ||
56 | (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); | ||
57 | |||
58 | *val= in_le16((unsigned short *)(pci_config_data + (offset&3))); | ||
59 | } | ||
60 | |||
61 | void cpc700_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, | ||
62 | unsigned char offset, unsigned short val) | ||
63 | { | ||
64 | out_le32(pci_config_address, | ||
65 | (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); | ||
66 | |||
67 | out_le16((unsigned short *)(pci_config_data + (offset&3)), val); | ||
68 | } | ||
69 | |||
70 | void cpc700_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, | ||
71 | unsigned char offset, unsigned int *val) | ||
72 | { | ||
73 | out_le32(pci_config_address, | ||
74 | (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); | ||
75 | |||
76 | *val= in_le32((unsigned *)pci_config_data); | ||
77 | } | ||
78 | |||
79 | void cpc700_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, | ||
80 | unsigned char offset, unsigned int val) | ||
81 | { | ||
82 | out_le32(pci_config_address, | ||
83 | (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); | ||
84 | |||
85 | out_le32((unsigned *)pci_config_data, val); | ||
86 | } | ||
87 | |||
88 | #define PCNET32_WIO_RDP 0x10 | ||
89 | #define PCNET32_WIO_RAP 0x12 | ||
90 | #define PCNET32_WIO_RESET 0x14 | ||
91 | |||
92 | #define PCNET32_DWIO_RDP 0x10 | ||
93 | #define PCNET32_DWIO_RAP 0x14 | ||
94 | #define PCNET32_DWIO_RESET 0x18 | ||
95 | |||
96 | /* Processor interface config register access */ | ||
97 | #define PIFCFGADDR 0xff500000 | ||
98 | #define PIFCFGDATA 0xff500004 | ||
99 | |||
100 | #define PLBMIFOPT 0x18 /* PLB Master Interface Options */ | ||
101 | |||
102 | #define MEM_MBEN 0x24 | ||
103 | #define MEM_TYPE 0x28 | ||
104 | #define MEM_B1SA 0x3c | ||
105 | #define MEM_B1EA 0x5c | ||
106 | #define MEM_B2SA 0x40 | ||
107 | #define MEM_B2EA 0x60 | ||
108 | |||
109 | unsigned long | ||
110 | get_mem_size(void) | ||
111 | { | ||
112 | int loop; | ||
113 | unsigned long mem_size = 0; | ||
114 | unsigned long mem_mben; | ||
115 | unsigned long mem_type; | ||
116 | unsigned long mem_start; | ||
117 | unsigned long mem_end; | ||
118 | volatile int *mem_addr = (int *)0xff500008; | ||
119 | volatile int *mem_data = (int *)0xff50000c; | ||
120 | |||
121 | /* Get the size of memory from the memory controller. */ | ||
122 | *mem_addr = MEM_MBEN; | ||
123 | asm("sync"); | ||
124 | mem_mben = *mem_data; | ||
125 | asm("sync"); | ||
126 | for(loop = 0; loop < 1000; loop++); | ||
127 | |||
128 | *mem_addr = MEM_TYPE; | ||
129 | asm("sync"); | ||
130 | mem_type = *mem_data; | ||
131 | asm("sync"); | ||
132 | for(loop = 0; loop < 1000; loop++); | ||
133 | |||
134 | *mem_addr = MEM_TYPE; | ||
135 | /* Confirm bank 1 has DRAM memory */ | ||
136 | if ((mem_mben & 0x40000000) && | ||
137 | ((mem_type & 0x30000000) == 0x10000000)) { | ||
138 | *mem_addr = MEM_B1SA; | ||
139 | asm("sync"); | ||
140 | mem_start = *mem_data; | ||
141 | asm("sync"); | ||
142 | for(loop = 0; loop < 1000; loop++); | ||
143 | |||
144 | *mem_addr = MEM_B1EA; | ||
145 | asm("sync"); | ||
146 | mem_end = *mem_data; | ||
147 | asm("sync"); | ||
148 | for(loop = 0; loop < 1000; loop++); | ||
149 | |||
150 | mem_size = mem_end - mem_start + 0x100000; | ||
151 | } | ||
152 | |||
153 | /* Confirm bank 2 has DRAM memory */ | ||
154 | if ((mem_mben & 0x20000000) && | ||
155 | ((mem_type & 0xc000000) == 0x4000000)) { | ||
156 | *mem_addr = MEM_B2SA; | ||
157 | asm("sync"); | ||
158 | mem_start = *mem_data; | ||
159 | asm("sync"); | ||
160 | for(loop = 0; loop < 1000; loop++); | ||
161 | |||
162 | *mem_addr = MEM_B2EA; | ||
163 | asm("sync"); | ||
164 | mem_end = *mem_data; | ||
165 | asm("sync"); | ||
166 | for(loop = 0; loop < 1000; loop++); | ||
167 | |||
168 | mem_size += mem_end - mem_start + 0x100000; | ||
169 | } | ||
170 | return mem_size; | ||
171 | } | ||
172 | |||
173 | unsigned long | ||
174 | load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, | ||
175 | void *ign1, void *ign2) | ||
176 | { | ||
177 | int csr0; | ||
178 | int csr_id; | ||
179 | int pci_devfn; | ||
180 | int found_multi = 0; | ||
181 | unsigned short vendor; | ||
182 | unsigned short device; | ||
183 | unsigned short command; | ||
184 | unsigned char header_type; | ||
185 | unsigned int bar0; | ||
186 | volatile int *pif_addr = (int *)0xff500000; | ||
187 | volatile int *pif_data = (int *)0xff500004; | ||
188 | |||
189 | /* | ||
190 | * Gah, these firmware guys need to learn that hardware | ||
191 | * byte swapping is evil! Disable all hardware byte | ||
192 | * swapping so it doesn't hurt anyone. | ||
193 | */ | ||
194 | *pif_addr = PLBMIFOPT; | ||
195 | asm("sync"); | ||
196 | *pif_data = 0x00000000; | ||
197 | asm("sync"); | ||
198 | |||
199 | /* Search out and turn off the PcNet ethernet boot device. */ | ||
200 | for (pci_devfn = 1; pci_devfn < 0xff; pci_devfn++) { | ||
201 | if (PCI_FUNC(pci_devfn) && !found_multi) | ||
202 | continue; | ||
203 | |||
204 | cpc700_pcibios_read_config_byte(0, pci_devfn, | ||
205 | PCI_HEADER_TYPE, &header_type); | ||
206 | |||
207 | if (!PCI_FUNC(pci_devfn)) | ||
208 | found_multi = header_type & 0x80; | ||
209 | |||
210 | cpc700_pcibios_read_config_word(0, pci_devfn, PCI_VENDOR_ID, | ||
211 | &vendor); | ||
212 | |||
213 | if (vendor != 0xffff) { | ||
214 | cpc700_pcibios_read_config_word(0, pci_devfn, | ||
215 | PCI_DEVICE_ID, &device); | ||
216 | |||
217 | /* If this PCI device is the Lance PCNet board then turn it off */ | ||
218 | if ((vendor == PCI_VENDOR_ID_AMD) && | ||
219 | (device == PCI_DEVICE_ID_AMD_LANCE)) { | ||
220 | |||
221 | /* Turn on I/O Space on the board. */ | ||
222 | cpc700_pcibios_read_config_word(0, pci_devfn, | ||
223 | PCI_COMMAND, &command); | ||
224 | command |= 0x1; | ||
225 | cpc700_pcibios_write_config_word(0, pci_devfn, | ||
226 | PCI_COMMAND, command); | ||
227 | |||
228 | /* Get the I/O space address */ | ||
229 | cpc700_pcibios_read_config_dword(0, pci_devfn, | ||
230 | PCI_BASE_ADDRESS_0, &bar0); | ||
231 | bar0 &= 0xfffffffe; | ||
232 | |||
233 | /* Reset the PCNet Board */ | ||
234 | inl (bar0+PCNET32_DWIO_RESET); | ||
235 | inw (bar0+PCNET32_WIO_RESET); | ||
236 | |||
237 | /* First do a work oriented read of csr0. If the value is | ||
238 | * 4 then this is the correct mode to access the board. | ||
239 | * If not try a double word ortiented read. | ||
240 | */ | ||
241 | outw(0, bar0 + PCNET32_WIO_RAP); | ||
242 | csr0 = inw(bar0 + PCNET32_WIO_RDP); | ||
243 | |||
244 | if (csr0 == 4) { | ||
245 | /* Check the Chip id register */ | ||
246 | outw(88, bar0 + PCNET32_WIO_RAP); | ||
247 | csr_id = inw(bar0 + PCNET32_WIO_RDP); | ||
248 | |||
249 | if (csr_id) { | ||
250 | /* This is the valid mode - set the stop bit */ | ||
251 | outw(0, bar0 + PCNET32_WIO_RAP); | ||
252 | outw(csr0, bar0 + PCNET32_WIO_RDP); | ||
253 | } | ||
254 | } else { | ||
255 | outl(0, bar0 + PCNET32_DWIO_RAP); | ||
256 | csr0 = inl(bar0 + PCNET32_DWIO_RDP); | ||
257 | if (csr0 == 4) { | ||
258 | /* Check the Chip id register */ | ||
259 | outl(88, bar0 + PCNET32_WIO_RAP); | ||
260 | csr_id = inl(bar0 + PCNET32_WIO_RDP); | ||
261 | |||
262 | if (csr_id) { | ||
263 | /* This is the valid mode - set the stop bit*/ | ||
264 | outl(0, bar0 + PCNET32_WIO_RAP); | ||
265 | outl(csr0, bar0 + PCNET32_WIO_RDP); | ||
266 | } | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | } | ||
271 | } | ||
272 | |||
273 | return decompress_kernel(load_addr, num_words, cksum); | ||
274 | } | ||
diff --git a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c new file mode 100644 index 000000000000..ab0f9902cb67 --- /dev/null +++ b/arch/ppc/boot/simple/misc.c | |||
@@ -0,0 +1,284 @@ | |||
1 | /* | ||
2 | * arch/ppc/simple/misc.c | ||
3 | * | ||
4 | * Misc. bootloader code for many machines. This assumes you have are using | ||
5 | * a 6xx/7xx/74xx CPU in your machine. This assumes the chunk of memory | ||
6 | * below 8MB is free. Finally, it assumes you have a NS16550-style uart for | ||
7 | * your serial console. If a machine meets these requirements, it can quite | ||
8 | * likely use this code during boot. | ||
9 | * | ||
10 | * Author: Matt Porter <mporter@mvista.com> | ||
11 | * Derived from arch/ppc/boot/prep/misc.c | ||
12 | * | ||
13 | * 2001 (c) MontaVista, Software, Inc. This file is licensed under | ||
14 | * the terms of the GNU General Public License version 2. This program | ||
15 | * is licensed "as is" without any warranty of any kind, whether express | ||
16 | * or implied. | ||
17 | */ | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | #include <linux/config.h> | ||
21 | #include <linux/string.h> | ||
22 | |||
23 | #include <asm/page.h> | ||
24 | #include <asm/mmu.h> | ||
25 | #include <asm/bootinfo.h> | ||
26 | #ifdef CONFIG_44x | ||
27 | #include <asm/ibm4xx.h> | ||
28 | #endif | ||
29 | #include <asm/reg.h> | ||
30 | |||
31 | #include "nonstdio.h" | ||
32 | |||
33 | /* Default cmdline */ | ||
34 | #ifdef CONFIG_CMDLINE | ||
35 | #define CMDLINE CONFIG_CMDLINE | ||
36 | #else | ||
37 | #define CMDLINE "" | ||
38 | #endif | ||
39 | |||
40 | /* Keyboard (and VGA console)? */ | ||
41 | #ifdef CONFIG_VGA_CONSOLE | ||
42 | #define HAS_KEYB 1 | ||
43 | #else | ||
44 | #define HAS_KEYB 0 | ||
45 | #endif | ||
46 | |||
47 | /* Will / Can the user give input? | ||
48 | * Val Henson has requested that Gemini doesn't wait for the | ||
49 | * user to edit the cmdline or not. | ||
50 | */ | ||
51 | #if (defined(CONFIG_SERIAL_8250_CONSOLE) \ | ||
52 | || defined(CONFIG_VGA_CONSOLE) \ | ||
53 | || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ | ||
54 | || defined(CONFIG_SERIAL_MPSC_CONSOLE)) \ | ||
55 | && !defined(CONFIG_GEMINI) | ||
56 | #define INTERACTIVE_CONSOLE 1 | ||
57 | #endif | ||
58 | |||
59 | char *avail_ram; | ||
60 | char *end_avail; | ||
61 | char *zimage_start; | ||
62 | char cmd_preset[] = CMDLINE; | ||
63 | char cmd_buf[256]; | ||
64 | char *cmd_line = cmd_buf; | ||
65 | int keyb_present = HAS_KEYB; | ||
66 | int zimage_size; | ||
67 | |||
68 | unsigned long com_port; | ||
69 | unsigned long initrd_size = 0; | ||
70 | |||
71 | /* The linker tells us various locations in the image */ | ||
72 | extern char __image_begin, __image_end; | ||
73 | extern char __ramdisk_begin, __ramdisk_end; | ||
74 | extern char _end[]; | ||
75 | /* Original location */ | ||
76 | extern unsigned long start; | ||
77 | |||
78 | extern int CRT_tstc(void); | ||
79 | extern unsigned long serial_init(int chan, void *ignored); | ||
80 | extern void serial_close(unsigned long com_port); | ||
81 | extern void gunzip(void *, int, unsigned char *, int *); | ||
82 | extern void serial_fixups(void); | ||
83 | |||
84 | /* Allow get_mem_size to be hooked into. This is the default. */ | ||
85 | unsigned long __attribute__ ((weak)) | ||
86 | get_mem_size(void) | ||
87 | { | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | struct bi_record * | ||
92 | decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) | ||
93 | { | ||
94 | #ifdef INTERACTIVE_CONSOLE | ||
95 | int timer = 0; | ||
96 | char ch; | ||
97 | #endif | ||
98 | char *cp; | ||
99 | struct bi_record *rec; | ||
100 | unsigned long initrd_loc = 0, TotalMemory = 0; | ||
101 | |||
102 | #if defined(CONFIG_SERIAL_8250_CONSOLE) || defined(CONFIG_SERIAL_MPSC_CONSOLE) | ||
103 | com_port = serial_init(0, NULL); | ||
104 | #endif | ||
105 | |||
106 | #if defined(CONFIG_44x) && defined(PPC44x_EMAC0_MR0) | ||
107 | /* Reset MAL */ | ||
108 | mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); | ||
109 | /* Wait for reset */ | ||
110 | while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; | ||
111 | /* Reset EMAC */ | ||
112 | *(volatile unsigned long *)PPC44x_EMAC0_MR0 = 0x20000000; | ||
113 | __asm__ __volatile__("eieio"); | ||
114 | #endif | ||
115 | |||
116 | /* | ||
117 | * Call get_mem_size(), which is memory controller dependent, | ||
118 | * and we must have the correct file linked in here. | ||
119 | */ | ||
120 | TotalMemory = get_mem_size(); | ||
121 | |||
122 | /* assume the chunk below 8M is free */ | ||
123 | end_avail = (char *)0x00800000; | ||
124 | |||
125 | /* | ||
126 | * Reveal where we were loaded at and where we | ||
127 | * were relocated to. | ||
128 | */ | ||
129 | puts("loaded at: "); puthex(load_addr); | ||
130 | puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); | ||
131 | puts("\n"); | ||
132 | if ( (unsigned long)load_addr != (unsigned long)&start ) | ||
133 | { | ||
134 | puts("relocated to: "); puthex((unsigned long)&start); | ||
135 | puts(" "); | ||
136 | puthex((unsigned long)((unsigned long)&start + (4*num_words))); | ||
137 | puts("\n"); | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * We link ourself to 0x00800000. When we run, we relocate | ||
142 | * ourselves there. So we just need __image_begin for the | ||
143 | * start. -- Tom | ||
144 | */ | ||
145 | zimage_start = (char *)(unsigned long)(&__image_begin); | ||
146 | zimage_size = (unsigned long)(&__image_end) - | ||
147 | (unsigned long)(&__image_begin); | ||
148 | |||
149 | initrd_size = (unsigned long)(&__ramdisk_end) - | ||
150 | (unsigned long)(&__ramdisk_begin); | ||
151 | |||
152 | /* | ||
153 | * The zImage and initrd will be between start and _end, so they've | ||
154 | * already been moved once. We're good to go now. -- Tom | ||
155 | */ | ||
156 | avail_ram = (char *)PAGE_ALIGN((unsigned long)_end); | ||
157 | puts("zimage at: "); puthex((unsigned long)zimage_start); | ||
158 | puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); | ||
159 | puts("\n"); | ||
160 | |||
161 | if ( initrd_size ) { | ||
162 | puts("initrd at: "); | ||
163 | puthex((unsigned long)(&__ramdisk_begin)); | ||
164 | puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n"); | ||
165 | } | ||
166 | |||
167 | avail_ram = (char *)0x00400000; | ||
168 | end_avail = (char *)0x00800000; | ||
169 | puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" "); | ||
170 | puthex((unsigned long)end_avail); puts("\n"); | ||
171 | |||
172 | if (keyb_present) | ||
173 | CRT_tstc(); /* Forces keyboard to be initialized */ | ||
174 | #ifdef CONFIG_GEMINI | ||
175 | /* | ||
176 | * If cmd_line is empty and cmd_preset is not, copy cmd_preset | ||
177 | * to cmd_line. This way we can override cmd_preset with the | ||
178 | * command line from Smon. | ||
179 | */ | ||
180 | |||
181 | if ( (cmd_line[0] == '\0') && (cmd_preset[0] != '\0')) | ||
182 | memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); | ||
183 | #endif | ||
184 | |||
185 | /* Display standard Linux/PPC boot prompt for kernel args */ | ||
186 | puts("\nLinux/PPC load: "); | ||
187 | cp = cmd_line; | ||
188 | memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); | ||
189 | while ( *cp ) putc(*cp++); | ||
190 | |||
191 | #ifdef INTERACTIVE_CONSOLE | ||
192 | /* | ||
193 | * If they have a console, allow them to edit the command line. | ||
194 | * Otherwise, don't bother wasting the five seconds. | ||
195 | */ | ||
196 | while (timer++ < 5*1000) { | ||
197 | if (tstc()) { | ||
198 | while ((ch = getc()) != '\n' && ch != '\r') { | ||
199 | /* Test for backspace/delete */ | ||
200 | if (ch == '\b' || ch == '\177') { | ||
201 | if (cp != cmd_line) { | ||
202 | cp--; | ||
203 | puts("\b \b"); | ||
204 | } | ||
205 | /* Test for ^x/^u (and wipe the line) */ | ||
206 | } else if (ch == '\030' || ch == '\025') { | ||
207 | while (cp != cmd_line) { | ||
208 | cp--; | ||
209 | puts("\b \b"); | ||
210 | } | ||
211 | } else { | ||
212 | *cp++ = ch; | ||
213 | putc(ch); | ||
214 | } | ||
215 | } | ||
216 | break; /* Exit 'timer' loop */ | ||
217 | } | ||
218 | udelay(1000); /* 1 msec */ | ||
219 | } | ||
220 | *cp = 0; | ||
221 | #endif | ||
222 | puts("\n"); | ||
223 | |||
224 | puts("Uncompressing Linux..."); | ||
225 | gunzip(0x0, 0x400000, zimage_start, &zimage_size); | ||
226 | puts("done.\n"); | ||
227 | |||
228 | /* get the bi_rec address */ | ||
229 | rec = bootinfo_addr(zimage_size); | ||
230 | |||
231 | /* We need to make sure that the initrd and bi_recs do not | ||
232 | * overlap. */ | ||
233 | if ( initrd_size ) { | ||
234 | unsigned long rec_loc = (unsigned long) rec; | ||
235 | initrd_loc = (unsigned long)(&__ramdisk_begin); | ||
236 | /* If the bi_recs are in the middle of the current | ||
237 | * initrd, move the initrd to the next MB | ||
238 | * boundary. */ | ||
239 | if ((rec_loc > initrd_loc) && | ||
240 | ((initrd_loc + initrd_size) > rec_loc)) { | ||
241 | initrd_loc = _ALIGN((unsigned long)(zimage_size) | ||
242 | + (2 << 20) - 1, (2 << 20)); | ||
243 | memmove((void *)initrd_loc, &__ramdisk_begin, | ||
244 | initrd_size); | ||
245 | puts("initrd moved: "); puthex(initrd_loc); | ||
246 | puts(" "); puthex(initrd_loc + initrd_size); | ||
247 | puts("\n"); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | bootinfo_init(rec); | ||
252 | if ( TotalMemory ) | ||
253 | bootinfo_append(BI_MEMSIZE, sizeof(int), (void*)&TotalMemory); | ||
254 | |||
255 | bootinfo_append(BI_CMD_LINE, strlen(cmd_line)+1, (void*)cmd_line); | ||
256 | |||
257 | /* add a bi_rec for the initrd if it exists */ | ||
258 | if (initrd_size) { | ||
259 | unsigned long initrd[2]; | ||
260 | |||
261 | initrd[0] = initrd_loc; | ||
262 | initrd[1] = initrd_size; | ||
263 | |||
264 | bootinfo_append(BI_INITRD, sizeof(initrd), &initrd); | ||
265 | } | ||
266 | puts("Now booting the kernel\n"); | ||
267 | serial_close(com_port); | ||
268 | |||
269 | return rec; | ||
270 | } | ||
271 | |||
272 | void __attribute__ ((weak)) | ||
273 | board_isa_init(void) | ||
274 | { | ||
275 | } | ||
276 | |||
277 | /* Allow decompress_kernel to be hooked into. This is the default. */ | ||
278 | void * __attribute__ ((weak)) | ||
279 | load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, | ||
280 | void *ign1, void *ign2) | ||
281 | { | ||
282 | board_isa_init(); | ||
283 | return decompress_kernel(load_addr, num_words, cksum); | ||
284 | } | ||
diff --git a/arch/ppc/boot/simple/mpc10x_memory.c b/arch/ppc/boot/simple/mpc10x_memory.c new file mode 100644 index 000000000000..977daedc14c0 --- /dev/null +++ b/arch/ppc/boot/simple/mpc10x_memory.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/common/mpc10x_common.c | ||
3 | * | ||
4 | * A routine to find out how much memory the machine has. | ||
5 | * | ||
6 | * Based on: | ||
7 | * arch/ppc/kernel/mpc10x_common.c | ||
8 | * | ||
9 | * Author: Mark A. Greer | ||
10 | * mgreer@mvista.com | ||
11 | * | ||
12 | * 2001-2002 (c) MontaVista, Software, Inc. This file is licensed under | ||
13 | * the terms of the GNU General Public License version 2. This program | ||
14 | * is licensed "as is" without any warranty of any kind, whether express | ||
15 | * or implied. | ||
16 | */ | ||
17 | |||
18 | #include <linux/pci.h> | ||
19 | #include <asm/types.h> | ||
20 | #include <asm/io.h> | ||
21 | #include "mpc10x.h" | ||
22 | |||
23 | /* | ||
24 | * *** WARNING - A BAT MUST be set to access the PCI config addr/data regs *** | ||
25 | */ | ||
26 | |||
27 | /* | ||
28 | * PCI config space macros, similar to indirect_xxx and early_xxx macros. | ||
29 | * We assume bus 0. | ||
30 | */ | ||
31 | #define MPC10X_CFG_read(val, addr, type, op) *val = op((type)(addr)) | ||
32 | #define MPC10X_CFG_write(val, addr, type, op) op((type *)(addr), (val)) | ||
33 | |||
34 | #define MPC10X_PCI_OP(rw, size, type, op, mask) \ | ||
35 | static void \ | ||
36 | mpc10x_##rw##_config_##size(unsigned int *cfg_addr, \ | ||
37 | unsigned int *cfg_data, int devfn, int offset, \ | ||
38 | type val) \ | ||
39 | { \ | ||
40 | out_be32(cfg_addr, \ | ||
41 | ((offset & 0xfc) << 24) | (devfn << 16) \ | ||
42 | | (0 << 8) | 0x80); \ | ||
43 | MPC10X_CFG_##rw(val, cfg_data + (offset & mask), type, op); \ | ||
44 | return; \ | ||
45 | } | ||
46 | |||
47 | MPC10X_PCI_OP(read, byte, u8 *, in_8, 3) | ||
48 | MPC10X_PCI_OP(read, dword, u32 *, in_le32, 0) | ||
49 | |||
50 | /* | ||
51 | * Read the memory controller registers to determine the amount of memory in | ||
52 | * the system. This assumes that the firmware has correctly set up the memory | ||
53 | * controller registers. On CONFIG_PPC_PREP, we know we are being called | ||
54 | * under a PReP memory map. On all other machines, we assume we are under | ||
55 | * a CHRP memory map. Further, on CONFIG_PPC_MULTIPLATFORM we must rename | ||
56 | * this function. | ||
57 | */ | ||
58 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
59 | #define get_mem_size mpc10x_get_mem_size | ||
60 | #endif | ||
61 | unsigned long | ||
62 | get_mem_size(void) | ||
63 | { | ||
64 | unsigned int *config_addr, *config_data, val; | ||
65 | unsigned long start, end, total, offset; | ||
66 | int i; | ||
67 | unsigned char bank_enables; | ||
68 | |||
69 | #ifdef CONFIG_PPC_PREP | ||
70 | config_addr = (unsigned int *)MPC10X_MAPA_CNFG_ADDR; | ||
71 | config_data = (unsigned int *)MPC10X_MAPA_CNFG_DATA; | ||
72 | #else | ||
73 | config_addr = (unsigned int *)MPC10X_MAPB_CNFG_ADDR; | ||
74 | config_data = (unsigned int *)MPC10X_MAPB_CNFG_DATA; | ||
75 | #endif | ||
76 | |||
77 | mpc10x_read_config_byte(config_addr, config_data, PCI_DEVFN(0,0), | ||
78 | MPC10X_MCTLR_MEM_BANK_ENABLES, &bank_enables); | ||
79 | |||
80 | total = 0; | ||
81 | |||
82 | for (i = 0; i < 8; i++) { | ||
83 | if (bank_enables & (1 << i)) { | ||
84 | offset = MPC10X_MCTLR_MEM_START_1 + ((i > 3) ? 4 : 0); | ||
85 | mpc10x_read_config_dword(config_addr, config_data, | ||
86 | PCI_DEVFN(0,0), offset, &val); | ||
87 | start = (val >> ((i & 3) << 3)) & 0xff; | ||
88 | |||
89 | offset = MPC10X_MCTLR_EXT_MEM_START_1 + ((i>3) ? 4 : 0); | ||
90 | mpc10x_read_config_dword(config_addr, config_data, | ||
91 | PCI_DEVFN(0,0), offset, &val); | ||
92 | val = (val >> ((i & 3) << 3)) & 0x03; | ||
93 | start = (val << 28) | (start << 20); | ||
94 | |||
95 | offset = MPC10X_MCTLR_MEM_END_1 + ((i > 3) ? 4 : 0); | ||
96 | mpc10x_read_config_dword(config_addr, config_data, | ||
97 | PCI_DEVFN(0,0), offset, &val); | ||
98 | end = (val >> ((i & 3) << 3)) & 0xff; | ||
99 | |||
100 | offset = MPC10X_MCTLR_EXT_MEM_END_1 + ((i > 3) ? 4 : 0); | ||
101 | mpc10x_read_config_dword(config_addr, config_data, | ||
102 | PCI_DEVFN(0,0), offset, &val); | ||
103 | val = (val >> ((i & 3) << 3)) & 0x03; | ||
104 | end = (val << 28) | (end << 20) | 0xfffff; | ||
105 | |||
106 | total += (end - start + 1); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | return total; | ||
111 | } | ||
diff --git a/arch/ppc/boot/simple/mpc52xx_tty.c b/arch/ppc/boot/simple/mpc52xx_tty.c new file mode 100644 index 000000000000..3acc6b7c0727 --- /dev/null +++ b/arch/ppc/boot/simple/mpc52xx_tty.c | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/mpc52xx_tty.c | ||
3 | * | ||
4 | * Minimal serial functions needed to send messages out a MPC52xx | ||
5 | * Programmable Serial Controller (PSC). | ||
6 | * | ||
7 | * Author: Dale Farnsworth <dfarnsworth@mvista.com> | ||
8 | * | ||
9 | * 2003-2004 (c) MontaVista, Software, Inc. This file is licensed under the | ||
10 | * terms of the GNU General Public License version 2. This program is licensed | ||
11 | * "as is" without any warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <asm/uaccess.h> | ||
17 | #include <asm/mpc52xx.h> | ||
18 | #include <asm/mpc52xx_psc.h> | ||
19 | #include <asm/serial.h> | ||
20 | #include <asm/io.h> | ||
21 | #include <asm/time.h> | ||
22 | |||
23 | |||
24 | #ifdef MPC52xx_PF_CONSOLE_PORT | ||
25 | #define MPC52xx_CONSOLE MPC52xx_PSCx_OFFSET(MPC52xx_PF_CONSOLE_PORT) | ||
26 | #define MPC52xx_PSC_CONFIG_SHIFT ((MPC52xx_PF_CONSOLE_PORT-1)<<2) | ||
27 | #else | ||
28 | #error "MPC52xx_PF_CONSOLE_PORT not defined" | ||
29 | #endif | ||
30 | |||
31 | static struct mpc52xx_psc __iomem *psc = | ||
32 | (struct mpc52xx_psc __iomem *) MPC52xx_PA(MPC52xx_CONSOLE); | ||
33 | |||
34 | /* The decrementer counts at the system bus clock frequency | ||
35 | * divided by four. The most accurate time base is connected to the | ||
36 | * rtc. We read the decrementer change during one rtc tick | ||
37 | * and multiply by 4 to get the system bus clock frequency. Since a | ||
38 | * rtc tick is one seconds, and that's pretty long, we change the rtc | ||
39 | * dividers temporarly to set them 64x faster ;) | ||
40 | */ | ||
41 | static int | ||
42 | mpc52xx_ipbfreq(void) | ||
43 | { | ||
44 | struct mpc52xx_rtc __iomem *rtc = | ||
45 | (struct mpc52xx_rtc __iomem *) MPC52xx_PA(MPC52xx_RTC_OFFSET); | ||
46 | struct mpc52xx_cdm __iomem *cdm = | ||
47 | (struct mpc52xx_cdm __iomem *) MPC52xx_PA(MPC52xx_CDM_OFFSET); | ||
48 | int current_time, previous_time; | ||
49 | int tbl_start, tbl_end; | ||
50 | int xlbfreq, ipbfreq; | ||
51 | |||
52 | out_be32(&rtc->dividers, 0x8f1f0000); /* Set RTC 64x faster */ | ||
53 | previous_time = in_be32(&rtc->time); | ||
54 | while ((current_time = in_be32(&rtc->time)) == previous_time) ; | ||
55 | tbl_start = get_tbl(); | ||
56 | previous_time = current_time; | ||
57 | while ((current_time = in_be32(&rtc->time)) == previous_time) ; | ||
58 | tbl_end = get_tbl(); | ||
59 | out_be32(&rtc->dividers, 0xffff0000); /* Restore RTC */ | ||
60 | |||
61 | xlbfreq = (tbl_end - tbl_start) << 8; | ||
62 | ipbfreq = (in_8(&cdm->ipb_clk_sel) & 1) ? xlbfreq / 2 : xlbfreq; | ||
63 | |||
64 | return ipbfreq; | ||
65 | } | ||
66 | |||
67 | unsigned long | ||
68 | serial_init(int ignored, void *ignored2) | ||
69 | { | ||
70 | struct mpc52xx_gpio __iomem *gpio = | ||
71 | (struct mpc52xx_gpio __iomem *) MPC52xx_PA(MPC52xx_GPIO_OFFSET); | ||
72 | int divisor; | ||
73 | int mode1; | ||
74 | int mode2; | ||
75 | u32 val32; | ||
76 | |||
77 | static int been_here = 0; | ||
78 | |||
79 | if (been_here) | ||
80 | return 0; | ||
81 | |||
82 | been_here = 1; | ||
83 | |||
84 | val32 = in_be32(&gpio->port_config); | ||
85 | val32 &= ~(0x7 << MPC52xx_PSC_CONFIG_SHIFT); | ||
86 | val32 |= MPC52xx_GPIO_PSC_CONFIG_UART_WITHOUT_CD | ||
87 | << MPC52xx_PSC_CONFIG_SHIFT; | ||
88 | out_be32(&gpio->port_config, val32); | ||
89 | |||
90 | out_8(&psc->command, MPC52xx_PSC_RST_TX | ||
91 | | MPC52xx_PSC_RX_DISABLE | MPC52xx_PSC_TX_ENABLE); | ||
92 | out_8(&psc->command, MPC52xx_PSC_RST_RX); | ||
93 | |||
94 | out_be32(&psc->sicr, 0x0); | ||
95 | out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); | ||
96 | out_be16(&psc->tfalarm, 0xf8); | ||
97 | |||
98 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1 | ||
99 | | MPC52xx_PSC_RX_ENABLE | ||
100 | | MPC52xx_PSC_TX_ENABLE); | ||
101 | |||
102 | divisor = ((mpc52xx_ipbfreq() | ||
103 | / (CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD * 16)) + 1) >> 1; | ||
104 | |||
105 | mode1 = MPC52xx_PSC_MODE_8_BITS | MPC52xx_PSC_MODE_PARNONE | ||
106 | | MPC52xx_PSC_MODE_ERR; | ||
107 | mode2 = MPC52xx_PSC_MODE_ONE_STOP; | ||
108 | |||
109 | out_8(&psc->ctur, divisor>>8); | ||
110 | out_8(&psc->ctlr, divisor); | ||
111 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); | ||
112 | out_8(&psc->mode, mode1); | ||
113 | out_8(&psc->mode, mode2); | ||
114 | |||
115 | return 0; /* ignored */ | ||
116 | } | ||
117 | |||
118 | void | ||
119 | serial_putc(void *ignored, const char c) | ||
120 | { | ||
121 | serial_init(0, NULL); | ||
122 | |||
123 | while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP)) ; | ||
124 | out_8(&psc->mpc52xx_psc_buffer_8, c); | ||
125 | while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP)) ; | ||
126 | } | ||
127 | |||
128 | char | ||
129 | serial_getc(void *ignored) | ||
130 | { | ||
131 | while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY)) ; | ||
132 | |||
133 | return in_8(&psc->mpc52xx_psc_buffer_8); | ||
134 | } | ||
135 | |||
136 | int | ||
137 | serial_tstc(void *ignored) | ||
138 | { | ||
139 | return (in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY) != 0; | ||
140 | } | ||
diff --git a/arch/ppc/boot/simple/mv64x60_tty.c b/arch/ppc/boot/simple/mv64x60_tty.c new file mode 100644 index 000000000000..5b45eb46b669 --- /dev/null +++ b/arch/ppc/boot/simple/mv64x60_tty.c | |||
@@ -0,0 +1,360 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/mv64x60_tty.c | ||
3 | * | ||
4 | * Bootloader version of the embedded MPSC/UART driver for the Marvell 64x60. | ||
5 | * Note: Due to a GT64260A erratum, DMA will be used for UART input (via SDMA). | ||
6 | * | ||
7 | * Author: Mark A. Greer <mgreer@mvista.com> | ||
8 | * | ||
9 | * 2001 (c) MontaVista Software, Inc. This file is licensed under | ||
10 | * the terms of the GNU General Public License version 2. This program | ||
11 | * is licensed "as is" without any warranty of any kind, whether express | ||
12 | * or implied. | ||
13 | */ | ||
14 | |||
15 | /* This code assumes that the data cache has been disabled (L1, L2, L3). */ | ||
16 | |||
17 | #include <linux/config.h> | ||
18 | #include <linux/types.h> | ||
19 | #include <linux/serial_reg.h> | ||
20 | #include <asm/serial.h> | ||
21 | #include <asm/io.h> | ||
22 | #include <asm/mv64x60_defs.h> | ||
23 | #include <mpsc_defs.h> | ||
24 | |||
25 | u32 mv64x60_console_baud = 9600; | ||
26 | u32 mv64x60_mpsc_clk_src = 8; /* TCLK */ | ||
27 | u32 mv64x60_mpsc_clk_freq = 100000000; | ||
28 | |||
29 | extern void udelay(long); | ||
30 | static void stop_dma(int chan); | ||
31 | |||
32 | static void __iomem *mv64x60_base = (void __iomem *)CONFIG_MV64X60_NEW_BASE; | ||
33 | |||
34 | struct sdma_regs { | ||
35 | u32 sdc; | ||
36 | u32 sdcm; | ||
37 | u32 rx_desc; | ||
38 | u32 rx_buf_ptr; | ||
39 | u32 scrdp; | ||
40 | u32 tx_desc; | ||
41 | u32 sctdp; | ||
42 | u32 sftdp; | ||
43 | }; | ||
44 | |||
45 | static struct sdma_regs sdma_regs[2]; | ||
46 | |||
47 | #define SDMA_REGS_INIT(s, reg_base) { \ | ||
48 | (s)->sdc = (reg_base) + SDMA_SDC; \ | ||
49 | (s)->sdcm = (reg_base) + SDMA_SDCM; \ | ||
50 | (s)->rx_desc = (reg_base) + SDMA_RX_DESC; \ | ||
51 | (s)->rx_buf_ptr = (reg_base) + SDMA_RX_BUF_PTR; \ | ||
52 | (s)->scrdp = (reg_base) + SDMA_SCRDP; \ | ||
53 | (s)->tx_desc = (reg_base) + SDMA_TX_DESC; \ | ||
54 | (s)->sctdp = (reg_base) + SDMA_SCTDP; \ | ||
55 | (s)->sftdp = (reg_base) + SDMA_SFTDP; \ | ||
56 | } | ||
57 | |||
58 | static u32 mpsc_base[2] = { MV64x60_MPSC_0_OFFSET, MV64x60_MPSC_1_OFFSET }; | ||
59 | |||
60 | struct mv64x60_rx_desc { | ||
61 | u16 bufsize; | ||
62 | u16 bytecnt; | ||
63 | u32 cmd_stat; | ||
64 | u32 next_desc_ptr; | ||
65 | u32 buffer; | ||
66 | }; | ||
67 | |||
68 | struct mv64x60_tx_desc { | ||
69 | u16 bytecnt; | ||
70 | u16 shadow; | ||
71 | u32 cmd_stat; | ||
72 | u32 next_desc_ptr; | ||
73 | u32 buffer; | ||
74 | }; | ||
75 | |||
76 | #define MAX_RESET_WAIT 10000 | ||
77 | #define MAX_TX_WAIT 10000 | ||
78 | |||
79 | #define RX_NUM_DESC 2 | ||
80 | #define TX_NUM_DESC 2 | ||
81 | |||
82 | #define RX_BUF_SIZE 32 | ||
83 | #define TX_BUF_SIZE 32 | ||
84 | |||
85 | static struct mv64x60_rx_desc rd[2][RX_NUM_DESC] __attribute__ ((aligned(32))); | ||
86 | static struct mv64x60_tx_desc td[2][TX_NUM_DESC] __attribute__ ((aligned(32))); | ||
87 | |||
88 | static char rx_buf[2][RX_NUM_DESC * RX_BUF_SIZE] __attribute__ ((aligned(32))); | ||
89 | static char tx_buf[2][TX_NUM_DESC * TX_BUF_SIZE] __attribute__ ((aligned(32))); | ||
90 | |||
91 | static int cur_rd[2] = { 0, 0 }; | ||
92 | static int cur_td[2] = { 0, 0 }; | ||
93 | |||
94 | static char chan_initialized[2] = { 0, 0 }; | ||
95 | |||
96 | |||
97 | #define RX_INIT_RDP(rdp) { \ | ||
98 | (rdp)->bufsize = 2; \ | ||
99 | (rdp)->bytecnt = 0; \ | ||
100 | (rdp)->cmd_stat = SDMA_DESC_CMDSTAT_L | SDMA_DESC_CMDSTAT_F | \ | ||
101 | SDMA_DESC_CMDSTAT_O; \ | ||
102 | } | ||
103 | |||
104 | #ifdef CONFIG_MV64360 | ||
105 | static u32 cpu2mem_tab[MV64x60_CPU2MEM_WINDOWS][2] = { | ||
106 | { MV64x60_CPU2MEM_0_BASE, MV64x60_CPU2MEM_0_SIZE }, | ||
107 | { MV64x60_CPU2MEM_1_BASE, MV64x60_CPU2MEM_1_SIZE }, | ||
108 | { MV64x60_CPU2MEM_2_BASE, MV64x60_CPU2MEM_2_SIZE }, | ||
109 | { MV64x60_CPU2MEM_3_BASE, MV64x60_CPU2MEM_3_SIZE } | ||
110 | }; | ||
111 | |||
112 | static u32 com2mem_tab[MV64x60_CPU2MEM_WINDOWS][2] = { | ||
113 | { MV64360_MPSC2MEM_0_BASE, MV64360_MPSC2MEM_0_SIZE }, | ||
114 | { MV64360_MPSC2MEM_1_BASE, MV64360_MPSC2MEM_1_SIZE }, | ||
115 | { MV64360_MPSC2MEM_2_BASE, MV64360_MPSC2MEM_2_SIZE }, | ||
116 | { MV64360_MPSC2MEM_3_BASE, MV64360_MPSC2MEM_3_SIZE } | ||
117 | }; | ||
118 | |||
119 | static u32 dram_selects[MV64x60_CPU2MEM_WINDOWS] = { 0xe, 0xd, 0xb, 0x7 }; | ||
120 | #endif | ||
121 | |||
122 | unsigned long | ||
123 | serial_init(int chan, void *ignored) | ||
124 | { | ||
125 | u32 mpsc_routing_base, sdma_base, brg_bcr, cdv; | ||
126 | int i; | ||
127 | |||
128 | chan = (chan == 1); /* default to chan 0 if anything but 1 */ | ||
129 | |||
130 | if (chan_initialized[chan]) | ||
131 | return chan; | ||
132 | |||
133 | chan_initialized[chan] = 1; | ||
134 | |||
135 | if (chan == 0) { | ||
136 | sdma_base = MV64x60_SDMA_0_OFFSET; | ||
137 | brg_bcr = MV64x60_BRG_0_OFFSET + BRG_BCR; | ||
138 | SDMA_REGS_INIT(&sdma_regs[0], MV64x60_SDMA_0_OFFSET); | ||
139 | } else { | ||
140 | sdma_base = MV64x60_SDMA_1_OFFSET; | ||
141 | brg_bcr = MV64x60_BRG_1_OFFSET + BRG_BCR; | ||
142 | SDMA_REGS_INIT(&sdma_regs[0], MV64x60_SDMA_1_OFFSET); | ||
143 | } | ||
144 | |||
145 | mpsc_routing_base = MV64x60_MPSC_ROUTING_OFFSET; | ||
146 | |||
147 | stop_dma(chan); | ||
148 | |||
149 | /* Set up ring buffers */ | ||
150 | for (i=0; i<RX_NUM_DESC; i++) { | ||
151 | RX_INIT_RDP(&rd[chan][i]); | ||
152 | rd[chan][i].buffer = (u32)&rx_buf[chan][i * RX_BUF_SIZE]; | ||
153 | rd[chan][i].next_desc_ptr = (u32)&rd[chan][i+1]; | ||
154 | } | ||
155 | rd[chan][RX_NUM_DESC - 1].next_desc_ptr = (u32)&rd[chan][0]; | ||
156 | |||
157 | for (i=0; i<TX_NUM_DESC; i++) { | ||
158 | td[chan][i].bytecnt = 0; | ||
159 | td[chan][i].shadow = 0; | ||
160 | td[chan][i].buffer = (u32)&tx_buf[chan][i * TX_BUF_SIZE]; | ||
161 | td[chan][i].cmd_stat = SDMA_DESC_CMDSTAT_F|SDMA_DESC_CMDSTAT_L; | ||
162 | td[chan][i].next_desc_ptr = (u32)&td[chan][i+1]; | ||
163 | } | ||
164 | td[chan][TX_NUM_DESC - 1].next_desc_ptr = (u32)&td[chan][0]; | ||
165 | |||
166 | /* Set MPSC Routing */ | ||
167 | out_le32(mv64x60_base + mpsc_routing_base + MPSC_MRR, 0x3ffffe38); | ||
168 | |||
169 | #ifdef CONFIG_GT64260 | ||
170 | out_le32(mv64x60_base + GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102); | ||
171 | #else /* Must be MV64360 or MV64460 */ | ||
172 | { | ||
173 | u32 enables, prot_bits, v; | ||
174 | |||
175 | /* Set up comm unit to memory mapping windows */ | ||
176 | /* Note: Assumes MV64x60_CPU2MEM_WINDOWS == 4 */ | ||
177 | |||
178 | enables = in_le32(mv64x60_base + MV64360_CPU_BAR_ENABLE) & 0xf; | ||
179 | prot_bits = 0; | ||
180 | |||
181 | for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) { | ||
182 | if (!(enables & (1 << i))) { | ||
183 | v = in_le32(mv64x60_base + cpu2mem_tab[i][0]); | ||
184 | v = ((v & 0xffff) << 16) | (dram_selects[i] << 8); | ||
185 | out_le32(mv64x60_base + com2mem_tab[i][0], v); | ||
186 | |||
187 | v = in_le32(mv64x60_base + cpu2mem_tab[i][1]); | ||
188 | v = (v & 0xffff) << 16; | ||
189 | out_le32(mv64x60_base + com2mem_tab[i][1], v); | ||
190 | |||
191 | prot_bits |= (0x3 << (i << 1)); /* r/w access */ | ||
192 | } | ||
193 | } | ||
194 | |||
195 | out_le32(mv64x60_base + MV64360_MPSC_0_REMAP, 0); | ||
196 | out_le32(mv64x60_base + MV64360_MPSC_1_REMAP, 0); | ||
197 | out_le32(mv64x60_base + MV64360_MPSC2MEM_ACC_PROT_0, prot_bits); | ||
198 | out_le32(mv64x60_base + MV64360_MPSC2MEM_ACC_PROT_1, prot_bits); | ||
199 | out_le32(mv64x60_base + MV64360_MPSC2MEM_BAR_ENABLE, enables); | ||
200 | } | ||
201 | #endif | ||
202 | |||
203 | /* MPSC 0/1 Rx & Tx get clocks BRG0/1 */ | ||
204 | out_le32(mv64x60_base + mpsc_routing_base + MPSC_RCRR, 0x00000100); | ||
205 | out_le32(mv64x60_base + mpsc_routing_base + MPSC_TCRR, 0x00000100); | ||
206 | |||
207 | /* clear pending interrupts */ | ||
208 | out_le32(mv64x60_base + MV64x60_SDMA_INTR_OFFSET + SDMA_INTR_MASK, 0); | ||
209 | |||
210 | out_le32(mv64x60_base + SDMA_SCRDP + sdma_base, (int)&rd[chan][0]); | ||
211 | out_le32(mv64x60_base + SDMA_SCTDP + sdma_base, | ||
212 | (int)&td[chan][TX_NUM_DESC - 1]); | ||
213 | out_le32(mv64x60_base + SDMA_SFTDP + sdma_base, | ||
214 | (int)&td[chan][TX_NUM_DESC - 1]); | ||
215 | |||
216 | out_le32(mv64x60_base + SDMA_SDC + sdma_base, | ||
217 | SDMA_SDC_RFT | SDMA_SDC_SFM | SDMA_SDC_BLMR | SDMA_SDC_BLMT | | ||
218 | (3 << 12)); | ||
219 | |||
220 | cdv = ((mv64x60_mpsc_clk_freq/(32*mv64x60_console_baud))-1); | ||
221 | out_le32(mv64x60_base + brg_bcr, | ||
222 | ((mv64x60_mpsc_clk_src << 18) | (1 << 16) | cdv)); | ||
223 | |||
224 | /* Put MPSC into UART mode, no null modem, 16x clock mode */ | ||
225 | out_le32(mv64x60_base + MPSC_MMCRL + mpsc_base[chan], 0x000004c4); | ||
226 | out_le32(mv64x60_base + MPSC_MMCRH + mpsc_base[chan], 0x04400400); | ||
227 | |||
228 | out_le32(mv64x60_base + MPSC_CHR_1 + mpsc_base[chan], 0); | ||
229 | out_le32(mv64x60_base + MPSC_CHR_9 + mpsc_base[chan], 0); | ||
230 | out_le32(mv64x60_base + MPSC_CHR_10 + mpsc_base[chan], 0); | ||
231 | out_le32(mv64x60_base + MPSC_CHR_3 + mpsc_base[chan], 4); | ||
232 | out_le32(mv64x60_base + MPSC_CHR_4 + mpsc_base[chan], 0); | ||
233 | out_le32(mv64x60_base + MPSC_CHR_5 + mpsc_base[chan], 0); | ||
234 | out_le32(mv64x60_base + MPSC_CHR_6 + mpsc_base[chan], 0); | ||
235 | out_le32(mv64x60_base + MPSC_CHR_7 + mpsc_base[chan], 0); | ||
236 | out_le32(mv64x60_base + MPSC_CHR_8 + mpsc_base[chan], 0); | ||
237 | |||
238 | /* 8 data bits, 1 stop bit */ | ||
239 | out_le32(mv64x60_base + MPSC_MPCR + mpsc_base[chan], (3 << 12)); | ||
240 | out_le32(mv64x60_base + SDMA_SDCM + sdma_base, SDMA_SDCM_ERD); | ||
241 | out_le32(mv64x60_base + MPSC_CHR_2 + mpsc_base[chan], MPSC_CHR_2_EH); | ||
242 | |||
243 | udelay(100); | ||
244 | |||
245 | return chan; | ||
246 | } | ||
247 | |||
248 | static void | ||
249 | stop_dma(int chan) | ||
250 | { | ||
251 | int i; | ||
252 | |||
253 | /* Abort MPSC Rx (aborting Tx messes things up) */ | ||
254 | out_le32(mv64x60_base + MPSC_CHR_2 + mpsc_base[chan], MPSC_CHR_2_RA); | ||
255 | |||
256 | /* Abort SDMA Rx, Tx */ | ||
257 | out_le32(mv64x60_base + sdma_regs[chan].sdcm, | ||
258 | SDMA_SDCM_AR | SDMA_SDCM_STD); | ||
259 | |||
260 | for (i=0; i<MAX_RESET_WAIT; i++) { | ||
261 | if ((in_le32(mv64x60_base + sdma_regs[chan].sdcm) & | ||
262 | (SDMA_SDCM_AR | SDMA_SDCM_AT)) == 0) | ||
263 | break; | ||
264 | |||
265 | udelay(100); | ||
266 | } | ||
267 | } | ||
268 | |||
269 | static int | ||
270 | wait_for_ownership(int chan) | ||
271 | { | ||
272 | int i; | ||
273 | |||
274 | for (i=0; i<MAX_TX_WAIT; i++) { | ||
275 | if ((in_le32(mv64x60_base + sdma_regs[chan].sdcm) & | ||
276 | SDMA_SDCM_TXD) == 0) | ||
277 | break; | ||
278 | |||
279 | udelay(1000); | ||
280 | } | ||
281 | |||
282 | return (i < MAX_TX_WAIT); | ||
283 | } | ||
284 | |||
285 | void | ||
286 | serial_putc(unsigned long com_port, unsigned char c) | ||
287 | { | ||
288 | struct mv64x60_tx_desc *tdp; | ||
289 | |||
290 | if (wait_for_ownership(com_port) == 0) | ||
291 | return; | ||
292 | |||
293 | tdp = &td[com_port][cur_td[com_port]]; | ||
294 | if (++cur_td[com_port] >= TX_NUM_DESC) | ||
295 | cur_td[com_port] = 0; | ||
296 | |||
297 | *(unchar *)(tdp->buffer ^ 7) = c; | ||
298 | tdp->bytecnt = 1; | ||
299 | tdp->shadow = 1; | ||
300 | tdp->cmd_stat = SDMA_DESC_CMDSTAT_L | SDMA_DESC_CMDSTAT_F | | ||
301 | SDMA_DESC_CMDSTAT_O; | ||
302 | |||
303 | out_le32(mv64x60_base + sdma_regs[com_port].sctdp, (int)tdp); | ||
304 | out_le32(mv64x60_base + sdma_regs[com_port].sftdp, (int)tdp); | ||
305 | out_le32(mv64x60_base + sdma_regs[com_port].sdcm, | ||
306 | in_le32(mv64x60_base + sdma_regs[com_port].sdcm) | | ||
307 | SDMA_SDCM_TXD); | ||
308 | } | ||
309 | |||
310 | unsigned char | ||
311 | serial_getc(unsigned long com_port) | ||
312 | { | ||
313 | struct mv64x60_rx_desc *rdp; | ||
314 | unchar c = '\0'; | ||
315 | |||
316 | rdp = &rd[com_port][cur_rd[com_port]]; | ||
317 | |||
318 | if ((rdp->cmd_stat & (SDMA_DESC_CMDSTAT_O|SDMA_DESC_CMDSTAT_ES)) == 0) { | ||
319 | c = *(unchar *)(rdp->buffer ^ 7); | ||
320 | RX_INIT_RDP(rdp); | ||
321 | if (++cur_rd[com_port] >= RX_NUM_DESC) | ||
322 | cur_rd[com_port] = 0; | ||
323 | } | ||
324 | |||
325 | return c; | ||
326 | } | ||
327 | |||
328 | int | ||
329 | serial_tstc(unsigned long com_port) | ||
330 | { | ||
331 | struct mv64x60_rx_desc *rdp; | ||
332 | int loop_count = 0; | ||
333 | int rc = 0; | ||
334 | |||
335 | rdp = &rd[com_port][cur_rd[com_port]]; | ||
336 | |||
337 | /* Go thru rcv desc's until empty looking for one with data (no error)*/ | ||
338 | while (((rdp->cmd_stat & SDMA_DESC_CMDSTAT_O) == 0) && | ||
339 | (loop_count++ < RX_NUM_DESC)) { | ||
340 | |||
341 | /* If there was an error, reinit the desc & continue */ | ||
342 | if ((rdp->cmd_stat & SDMA_DESC_CMDSTAT_ES) != 0) { | ||
343 | RX_INIT_RDP(rdp); | ||
344 | if (++cur_rd[com_port] >= RX_NUM_DESC) | ||
345 | cur_rd[com_port] = 0; | ||
346 | rdp = (struct mv64x60_rx_desc *)rdp->next_desc_ptr; | ||
347 | } else { | ||
348 | rc = 1; | ||
349 | break; | ||
350 | } | ||
351 | } | ||
352 | |||
353 | return rc; | ||
354 | } | ||
355 | |||
356 | void | ||
357 | serial_close(unsigned long com_port) | ||
358 | { | ||
359 | stop_dma(com_port); | ||
360 | } | ||
diff --git a/arch/ppc/boot/simple/openbios.c b/arch/ppc/boot/simple/openbios.c new file mode 100644 index 000000000000..c732b6d70cfb --- /dev/null +++ b/arch/ppc/boot/simple/openbios.c | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/openbios.c | ||
3 | * | ||
4 | * 2005 (c) SYSGO AG - g.jaeger@sysgo.com | ||
5 | * This file is licensed under the terms of the GNU General Public | ||
6 | * License version 2. This program is licensed "as is" without | ||
7 | * any warranty of any kind, whether express or implied. | ||
8 | * | ||
9 | * Derived from arch/ppc/boot/simple/pibs.c (from MontaVista) | ||
10 | */ | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | #include <linux/config.h> | ||
14 | #include <linux/string.h> | ||
15 | #include <asm/ppcboot.h> | ||
16 | #include <platforms/4xx/ebony.h> | ||
17 | |||
18 | extern unsigned long decompress_kernel(unsigned long load_addr, int num_words, | ||
19 | unsigned long cksum); | ||
20 | |||
21 | /* We need to make sure that this is before the images to ensure | ||
22 | * that it's in a mapped location. */ | ||
23 | bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot"))); | ||
24 | bd_t *hold_residual = &hold_resid_buf; | ||
25 | |||
26 | void * | ||
27 | load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, | ||
28 | void *ign1, void *ign2) | ||
29 | { | ||
30 | decompress_kernel(load_addr, num_words, cksum); | ||
31 | |||
32 | /* simply copy the MAC addresses */ | ||
33 | memcpy(hold_residual->bi_enetaddr, (char *)EBONY_OPENBIOS_MAC_BASE, 6); | ||
34 | memcpy(hold_residual->bi_enet1addr, (char *)(EBONY_OPENBIOS_MAC_BASE+EBONY_OPENBIOS_MAC_OFFSET), 6); | ||
35 | |||
36 | return (void *)hold_residual; | ||
37 | } | ||
diff --git a/arch/ppc/boot/simple/pci.c b/arch/ppc/boot/simple/pci.c new file mode 100644 index 000000000000..b0f673c8b7d9 --- /dev/null +++ b/arch/ppc/boot/simple/pci.c | |||
@@ -0,0 +1,274 @@ | |||
1 | /* Stand alone funtions for QSpan Tundra support. | ||
2 | */ | ||
3 | #include <linux/types.h> | ||
4 | #include <linux/pci.h> | ||
5 | #include <asm/mpc8xx.h> | ||
6 | |||
7 | extern void puthex(unsigned long val); | ||
8 | extern void puts(const char *); | ||
9 | |||
10 | /* To map PCI devices, you first write 0xffffffff into the device | ||
11 | * base address registers. When the register is read back, the | ||
12 | * number of most significant '1' bits describes the amount of address | ||
13 | * space needed for mapping. If the most significant bit is not set, | ||
14 | * either the device does not use that address register, or it has | ||
15 | * a fixed address that we can't change. After the address is assigned, | ||
16 | * the command register has to be written to enable the card. | ||
17 | */ | ||
18 | typedef struct { | ||
19 | u_char pci_bus; | ||
20 | u_char pci_devfn; | ||
21 | ushort pci_command; | ||
22 | uint pci_addrs[6]; | ||
23 | } pci_map_t; | ||
24 | |||
25 | /* We should probably dynamically allocate these structures. | ||
26 | */ | ||
27 | #define MAX_PCI_DEVS 32 | ||
28 | int pci_dev_cnt; | ||
29 | pci_map_t pci_map[MAX_PCI_DEVS]; | ||
30 | |||
31 | void pci_conf_write(int bus, int device, int func, int reg, uint writeval); | ||
32 | void pci_conf_read(int bus, int device, int func, int reg, void *readval); | ||
33 | void probe_addresses(int bus, int devfn); | ||
34 | void map_pci_addrs(void); | ||
35 | |||
36 | extern int | ||
37 | qs_pci_read_config_byte(unsigned char bus, unsigned char dev_fn, | ||
38 | unsigned char offset, unsigned char *val); | ||
39 | extern int | ||
40 | qs_pci_read_config_word(unsigned char bus, unsigned char dev_fn, | ||
41 | unsigned char offset, unsigned short *val); | ||
42 | extern int | ||
43 | qs_pci_read_config_dword(unsigned char bus, unsigned char dev_fn, | ||
44 | unsigned char offset, unsigned int *val); | ||
45 | extern int | ||
46 | qs_pci_write_config_byte(unsigned char bus, unsigned char dev_fn, | ||
47 | unsigned char offset, unsigned char val); | ||
48 | extern int | ||
49 | qs_pci_write_config_word(unsigned char bus, unsigned char dev_fn, | ||
50 | unsigned char offset, unsigned short val); | ||
51 | extern int | ||
52 | qs_pci_write_config_dword(unsigned char bus, unsigned char dev_fn, | ||
53 | unsigned char offset, unsigned int val); | ||
54 | |||
55 | |||
56 | /* This is a really stripped version of PCI bus scan. All we are | ||
57 | * looking for are devices that exist. | ||
58 | */ | ||
59 | void | ||
60 | pci_scanner(int addr_probe) | ||
61 | { | ||
62 | unsigned int devfn, l, class, bus_number; | ||
63 | unsigned char hdr_type, is_multi; | ||
64 | |||
65 | is_multi = 0; | ||
66 | bus_number = 0; | ||
67 | for (devfn = 0; devfn < 0xff; ++devfn) { | ||
68 | /* The device numbers are comprised of upper 5 bits of | ||
69 | * device number and lower 3 bits of multi-function number. | ||
70 | */ | ||
71 | if ((devfn & 7) && !is_multi) { | ||
72 | /* Don't scan multifunction addresses if this is | ||
73 | * not a multifunction device. | ||
74 | */ | ||
75 | continue; | ||
76 | } | ||
77 | |||
78 | /* Read the header to determine card type. | ||
79 | */ | ||
80 | qs_pci_read_config_byte(bus_number, devfn, PCI_HEADER_TYPE, | ||
81 | &hdr_type); | ||
82 | |||
83 | /* If this is a base device number, check the header to | ||
84 | * determine if it is mulifunction. | ||
85 | */ | ||
86 | if ((devfn & 7) == 0) | ||
87 | is_multi = hdr_type & 0x80; | ||
88 | |||
89 | /* Check to see if the board is really in the slot. | ||
90 | */ | ||
91 | qs_pci_read_config_dword(bus_number, devfn, PCI_VENDOR_ID, &l); | ||
92 | /* some broken boards return 0 if a slot is empty: */ | ||
93 | if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || | ||
94 | l == 0xffff0000) { | ||
95 | /* Nothing there. | ||
96 | */ | ||
97 | is_multi = 0; | ||
98 | continue; | ||
99 | } | ||
100 | |||
101 | /* If we are not performing an address probe, | ||
102 | * just simply print out some information. | ||
103 | */ | ||
104 | if (!addr_probe) { | ||
105 | qs_pci_read_config_dword(bus_number, devfn, | ||
106 | PCI_CLASS_REVISION, &class); | ||
107 | |||
108 | class >>= 8; /* upper 3 bytes */ | ||
109 | |||
110 | #if 0 | ||
111 | printf("Found (%3d:%d): vendor 0x%04x, device 0x%04x, class 0x%06x\n", | ||
112 | (devfn >> 3), (devfn & 7), | ||
113 | (l & 0xffff), (l >> 16) & 0xffff, class); | ||
114 | #else | ||
115 | puts("Found ("); puthex(devfn >> 3); | ||
116 | puts(":"); puthex(devfn & 7); | ||
117 | puts("): vendor "); puthex(l & 0xffff); | ||
118 | puts(", device "); puthex((l >> 16) & 0xffff); | ||
119 | puts(", class "); puthex(class); puts("\n"); | ||
120 | #endif | ||
121 | } | ||
122 | else { | ||
123 | /* If this is a "normal" device, build address list. | ||
124 | */ | ||
125 | if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_NORMAL) | ||
126 | probe_addresses(bus_number, devfn); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | /* Now map the boards. | ||
131 | */ | ||
132 | if (addr_probe) | ||
133 | map_pci_addrs(); | ||
134 | } | ||
135 | |||
136 | /* Probe addresses for the specified device. This is a destructive | ||
137 | * operation because it writes the registers. | ||
138 | */ | ||
139 | void | ||
140 | probe_addresses(bus, devfn) | ||
141 | { | ||
142 | int i; | ||
143 | uint pciaddr; | ||
144 | ushort pcicmd; | ||
145 | pci_map_t *pm; | ||
146 | |||
147 | if (pci_dev_cnt >= MAX_PCI_DEVS) { | ||
148 | puts("Too many PCI devices\n"); | ||
149 | return; | ||
150 | } | ||
151 | |||
152 | pm = &pci_map[pci_dev_cnt++]; | ||
153 | |||
154 | pm->pci_bus = bus; | ||
155 | pm->pci_devfn = devfn; | ||
156 | |||
157 | for (i=0; i<6; i++) { | ||
158 | qs_pci_write_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4), -1); | ||
159 | qs_pci_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4), | ||
160 | &pciaddr); | ||
161 | pm->pci_addrs[i] = pciaddr; | ||
162 | qs_pci_read_config_word(bus, devfn, PCI_COMMAND, &pcicmd); | ||
163 | pm->pci_command = pcicmd; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | /* Map the cards into the PCI space. The PCI has separate memory | ||
168 | * and I/O spaces. In addition, some memory devices require mapping | ||
169 | * below 1M. The least significant 4 bits of the address register | ||
170 | * provide information. If this is an I/O device, only the LS bit | ||
171 | * is used to indicate that, so I/O devices can be mapped to a two byte | ||
172 | * boundard. Memory addresses can be mapped to a 32 byte boundary. | ||
173 | * The QSpan implementations usually have a 1Gbyte space for each | ||
174 | * memory and I/O spaces. | ||
175 | * | ||
176 | * This isn't a terribly fancy algorithm. I just map the spaces from | ||
177 | * the top starting with the largest address space. When finished, | ||
178 | * the registers are written and the card enabled. | ||
179 | * | ||
180 | * While the Tundra can map a large address space on most boards, we | ||
181 | * need to be careful because it may overlap other devices (like IMMR). | ||
182 | */ | ||
183 | #define MEMORY_SPACE_SIZE 0x20000000 | ||
184 | #define IO_SPACE_SIZE 0x20000000 | ||
185 | |||
186 | void | ||
187 | map_pci_addrs() | ||
188 | { | ||
189 | uint pci_mem_top, pci_mem_low; | ||
190 | uint pci_io_top; | ||
191 | uint addr_mask, reg_addr, space; | ||
192 | int i, j; | ||
193 | pci_map_t *pm; | ||
194 | |||
195 | pci_mem_top = MEMORY_SPACE_SIZE; | ||
196 | pci_io_top = IO_SPACE_SIZE; | ||
197 | pci_mem_low = (1 * 1024 * 1024); /* Below one meg addresses */ | ||
198 | |||
199 | /* We can't map anything more than the maximum space, but test | ||
200 | * for it anyway to catch devices out of range. | ||
201 | */ | ||
202 | addr_mask = 0x80000000; | ||
203 | |||
204 | do { | ||
205 | space = (~addr_mask) + 1; /* Size of the space */ | ||
206 | for (i=0; i<pci_dev_cnt; i++) { | ||
207 | pm = &pci_map[i]; | ||
208 | for (j=0; j<6; j++) { | ||
209 | /* If the MS bit is not set, this has either | ||
210 | * already been mapped, or is not used. | ||
211 | */ | ||
212 | reg_addr = pm->pci_addrs[j]; | ||
213 | if ((reg_addr & 0x80000000) == 0) | ||
214 | continue; | ||
215 | if (reg_addr & PCI_BASE_ADDRESS_SPACE_IO) { | ||
216 | if ((reg_addr & PCI_BASE_ADDRESS_IO_MASK) != addr_mask) | ||
217 | continue; | ||
218 | if (pci_io_top < space) { | ||
219 | puts("Out of PCI I/O space\n"); | ||
220 | } | ||
221 | else { | ||
222 | pci_io_top -= space; | ||
223 | pm->pci_addrs[j] = pci_io_top; | ||
224 | pm->pci_command |= PCI_COMMAND_IO; | ||
225 | } | ||
226 | } | ||
227 | else { | ||
228 | if ((reg_addr & PCI_BASE_ADDRESS_MEM_MASK) != addr_mask) | ||
229 | continue; | ||
230 | |||
231 | /* Memory space. Test if below 1M. | ||
232 | */ | ||
233 | if (reg_addr & PCI_BASE_ADDRESS_MEM_TYPE_1M) { | ||
234 | if (pci_mem_low < space) { | ||
235 | puts("Out of PCI 1M space\n"); | ||
236 | } | ||
237 | else { | ||
238 | pci_mem_low -= space; | ||
239 | pm->pci_addrs[j] = pci_mem_low; | ||
240 | } | ||
241 | } | ||
242 | else { | ||
243 | if (pci_mem_top < space) { | ||
244 | puts("Out of PCI Mem space\n"); | ||
245 | } | ||
246 | else { | ||
247 | pci_mem_top -= space; | ||
248 | pm->pci_addrs[j] = pci_mem_top; | ||
249 | } | ||
250 | } | ||
251 | pm->pci_command |= PCI_COMMAND_MEMORY; | ||
252 | } | ||
253 | } | ||
254 | } | ||
255 | addr_mask >>= 1; | ||
256 | addr_mask |= 0x80000000; | ||
257 | } while (addr_mask != 0xfffffffe); | ||
258 | |||
259 | /* Now, run the list one more time and map everything. | ||
260 | */ | ||
261 | for (i=0; i<pci_dev_cnt; i++) { | ||
262 | pm = &pci_map[i]; | ||
263 | for (j=0; j<6; j++) { | ||
264 | qs_pci_write_config_dword(pm->pci_bus, pm->pci_devfn, | ||
265 | PCI_BASE_ADDRESS_0 + (j * 4), pm->pci_addrs[j]); | ||
266 | } | ||
267 | |||
268 | /* Enable memory or address mapping. | ||
269 | */ | ||
270 | qs_pci_write_config_word(pm->pci_bus, pm->pci_devfn, PCI_COMMAND, | ||
271 | pm->pci_command); | ||
272 | } | ||
273 | } | ||
274 | |||
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 | } | ||
diff --git a/arch/ppc/boot/simple/prepmap.c b/arch/ppc/boot/simple/prepmap.c new file mode 100644 index 000000000000..c871a4db6e8c --- /dev/null +++ b/arch/ppc/boot/simple/prepmap.c | |||
@@ -0,0 +1,12 @@ | |||
1 | /* | ||
2 | * 2004 (C) IBM. This file is licensed under the terms of the GNU General | ||
3 | * Public License version 2. This program is licensed "as is" without any | ||
4 | * warranty of any kind, whether express or implied. | ||
5 | */ | ||
6 | |||
7 | #include <nonstdio.h> | ||
8 | |||
9 | void board_isa_init(void) | ||
10 | { | ||
11 | ISA_init(0x80000000); | ||
12 | } | ||
diff --git a/arch/ppc/boot/simple/qspan_pci.c b/arch/ppc/boot/simple/qspan_pci.c new file mode 100644 index 000000000000..d2966d032a4c --- /dev/null +++ b/arch/ppc/boot/simple/qspan_pci.c | |||
@@ -0,0 +1,269 @@ | |||
1 | /* | ||
2 | * LinuxPPC arch/ppc/kernel/qspan_pci.c Dan Malek (dmalek@jlc.net) | ||
3 | * | ||
4 | * QSpan Motorola bus to PCI bridge. The config address register | ||
5 | * is located 0x500 from the base of the bridge control/status registers. | ||
6 | * The data register is located at 0x504. | ||
7 | * This is a two step operation. First, the address register is written, | ||
8 | * then the data register is read/written as required. | ||
9 | * I don't know what to do about interrupts (yet). | ||
10 | */ | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/pci.h> | ||
15 | #include <asm/mpc8xx.h> | ||
16 | |||
17 | /* | ||
18 | * When reading the configuration space, if something does not respond | ||
19 | * the bus times out and we get a machine check interrupt. So, the | ||
20 | * good ol' exception tables come to mind to trap it and return some | ||
21 | * value. | ||
22 | * | ||
23 | * On an error we just return a -1, since that is what the caller wants | ||
24 | * returned if nothing is present. I copied this from __get_user_asm, | ||
25 | * with the only difference of returning -1 instead of EFAULT. | ||
26 | * There is an associated hack in the machine check trap code. | ||
27 | * | ||
28 | * The QSPAN is also a big endian device, that is it makes the PCI | ||
29 | * look big endian to us. This presents a problem for the Linux PCI | ||
30 | * functions, which assume little endian. For example, we see the | ||
31 | * first 32-bit word like this: | ||
32 | * ------------------------ | ||
33 | * | Device ID | Vendor ID | | ||
34 | * ------------------------ | ||
35 | * If we read/write as a double word, that's OK. But in our world, | ||
36 | * when read as a word, device ID is at location 0, not location 2 as | ||
37 | * the little endian PCI would believe. We have to switch bits in | ||
38 | * the PCI addresses given to us to get the data to/from the correct | ||
39 | * byte lanes. | ||
40 | * | ||
41 | * The QSPAN only supports 4 bits of "slot" in the dev_fn instead of 5. | ||
42 | * It always forces the MS bit to zero. Therefore, dev_fn values | ||
43 | * greater than 128 are returned as "no device found" errors. | ||
44 | * | ||
45 | * The QSPAN can only perform long word (32-bit) configuration cycles. | ||
46 | * The "offset" must have the two LS bits set to zero. Read operations | ||
47 | * require we read the entire word and then sort out what should be | ||
48 | * returned. Write operations other than long word require that we | ||
49 | * read the long word, update the proper word or byte, then write the | ||
50 | * entire long word back. | ||
51 | * | ||
52 | * PCI Bridge hack. We assume (correctly) that bus 0 is the primary | ||
53 | * PCI bus from the QSPAN. If we are called with a bus number other | ||
54 | * than zero, we create a Type 1 configuration access that a downstream | ||
55 | * PCI bridge will interpret. | ||
56 | */ | ||
57 | |||
58 | #define __get_pci_config(x, addr, op) \ | ||
59 | __asm__ __volatile__( \ | ||
60 | "1: "op" %0,0(%1)\n" \ | ||
61 | " eieio\n" \ | ||
62 | "2:\n" \ | ||
63 | ".section .fixup,\"ax\"\n" \ | ||
64 | "3: li %0,-1\n" \ | ||
65 | " b 2b\n" \ | ||
66 | ".section __ex_table,\"a\"\n" \ | ||
67 | " .align 2\n" \ | ||
68 | " .long 1b,3b\n" \ | ||
69 | ".text" \ | ||
70 | : "=r"(x) : "r"(addr)) | ||
71 | |||
72 | #define QS_CONFIG_ADDR ((volatile uint *)(PCI_CSR_ADDR + 0x500)) | ||
73 | #define QS_CONFIG_DATA ((volatile uint *)(PCI_CSR_ADDR + 0x504)) | ||
74 | |||
75 | #define mk_config_addr(bus, dev, offset) \ | ||
76 | (((bus)<<16) | ((dev)<<8) | (offset & 0xfc)) | ||
77 | |||
78 | #define mk_config_type1(bus, dev, offset) \ | ||
79 | mk_config_addr(bus, dev, offset) | 1; | ||
80 | |||
81 | /* Initialize the QSpan device registers after power up. | ||
82 | */ | ||
83 | void | ||
84 | qspan_init(void) | ||
85 | { | ||
86 | uint *qptr; | ||
87 | |||
88 | |||
89 | |||
90 | qptr = (uint *)PCI_CSR_ADDR; | ||
91 | |||
92 | /* PCI Configuration/status. Upper bits written to clear | ||
93 | * pending interrupt or status. Lower bits enable QSPAN as | ||
94 | * PCI master, enable memory and I/O cycles, and enable PCI | ||
95 | * parity error checking. | ||
96 | * IMPORTANT: The last two bits of this word enable PCI | ||
97 | * master cycles into the QBus. The QSpan is broken and can't | ||
98 | * meet the timing specs of the PQ bus for this to work. Therefore, | ||
99 | * if you don't have external bus arbitration, you can't use | ||
100 | * this function. | ||
101 | */ | ||
102 | #ifdef EXTERNAL_PQ_ARB | ||
103 | qptr[1] = 0xf9000147; | ||
104 | #else | ||
105 | qptr[1] = 0xf9000144; | ||
106 | #endif | ||
107 | |||
108 | /* PCI Misc configuration. Set PCI latency timer resolution | ||
109 | * of 8 cycles, set cache size to 4 x 32. | ||
110 | */ | ||
111 | qptr[3] = 0; | ||
112 | |||
113 | /* Set up PCI Target address mapping. Enable, Posted writes, | ||
114 | * 2Gbyte space (processor memory controller determines actual size). | ||
115 | */ | ||
116 | qptr[64] = 0x8f000080; | ||
117 | |||
118 | /* Map processor 0x80000000 to PCI 0x00000000. | ||
119 | * Processor address bit 1 determines I/O type access (0x80000000) | ||
120 | * or memory type access (0xc0000000). | ||
121 | */ | ||
122 | qptr[65] = 0x80000000; | ||
123 | |||
124 | /* Enable error logging and clear any pending error status. | ||
125 | */ | ||
126 | qptr[80] = 0x90000000; | ||
127 | |||
128 | qptr[512] = 0x000c0003; | ||
129 | |||
130 | /* Set up Qbus slave image. | ||
131 | */ | ||
132 | qptr[960] = 0x01000000; | ||
133 | qptr[961] = 0x000000d1; | ||
134 | qptr[964] = 0x00000000; | ||
135 | qptr[965] = 0x000000d1; | ||
136 | |||
137 | } | ||
138 | |||
139 | /* Functions to support PCI bios-like features to read/write configuration | ||
140 | * space. If the function fails for any reason, a -1 (0xffffffff) value | ||
141 | * must be returned. | ||
142 | */ | ||
143 | #define DEVICE_NOT_FOUND (-1) | ||
144 | #define SUCCESSFUL 0 | ||
145 | |||
146 | int qs_pci_read_config_byte(unsigned char bus, unsigned char dev_fn, | ||
147 | unsigned char offset, unsigned char *val) | ||
148 | { | ||
149 | uint temp; | ||
150 | u_char *cp; | ||
151 | |||
152 | if ((bus > 7) || (dev_fn > 127)) { | ||
153 | *val = 0xff; | ||
154 | return DEVICE_NOT_FOUND; | ||
155 | } | ||
156 | |||
157 | if (bus == 0) | ||
158 | *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); | ||
159 | else | ||
160 | *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); | ||
161 | __get_pci_config(temp, QS_CONFIG_DATA, "lwz"); | ||
162 | |||
163 | offset ^= 0x03; | ||
164 | cp = ((u_char *)&temp) + (offset & 0x03); | ||
165 | *val = *cp; | ||
166 | return SUCCESSFUL; | ||
167 | } | ||
168 | |||
169 | int qs_pci_read_config_word(unsigned char bus, unsigned char dev_fn, | ||
170 | unsigned char offset, unsigned short *val) | ||
171 | { | ||
172 | uint temp; | ||
173 | ushort *sp; | ||
174 | |||
175 | if ((bus > 7) || (dev_fn > 127)) { | ||
176 | *val = 0xffff; | ||
177 | return DEVICE_NOT_FOUND; | ||
178 | } | ||
179 | |||
180 | if (bus == 0) | ||
181 | *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); | ||
182 | else | ||
183 | *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); | ||
184 | __get_pci_config(temp, QS_CONFIG_DATA, "lwz"); | ||
185 | offset ^= 0x02; | ||
186 | |||
187 | sp = ((ushort *)&temp) + ((offset >> 1) & 1); | ||
188 | *val = *sp; | ||
189 | return SUCCESSFUL; | ||
190 | } | ||
191 | |||
192 | int qs_pci_read_config_dword(unsigned char bus, unsigned char dev_fn, | ||
193 | unsigned char offset, unsigned int *val) | ||
194 | { | ||
195 | if ((bus > 7) || (dev_fn > 127)) { | ||
196 | *val = 0xffffffff; | ||
197 | return DEVICE_NOT_FOUND; | ||
198 | } | ||
199 | if (bus == 0) | ||
200 | *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); | ||
201 | else | ||
202 | *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); | ||
203 | __get_pci_config(*val, QS_CONFIG_DATA, "lwz"); | ||
204 | return SUCCESSFUL; | ||
205 | } | ||
206 | |||
207 | int qs_pci_write_config_byte(unsigned char bus, unsigned char dev_fn, | ||
208 | unsigned char offset, unsigned char val) | ||
209 | { | ||
210 | uint temp; | ||
211 | u_char *cp; | ||
212 | |||
213 | if ((bus > 7) || (dev_fn > 127)) | ||
214 | return DEVICE_NOT_FOUND; | ||
215 | |||
216 | qs_pci_read_config_dword(bus, dev_fn, offset, &temp); | ||
217 | |||
218 | offset ^= 0x03; | ||
219 | cp = ((u_char *)&temp) + (offset & 0x03); | ||
220 | *cp = val; | ||
221 | |||
222 | if (bus == 0) | ||
223 | *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); | ||
224 | else | ||
225 | *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); | ||
226 | *QS_CONFIG_DATA = temp; | ||
227 | |||
228 | return SUCCESSFUL; | ||
229 | } | ||
230 | |||
231 | int qs_pci_write_config_word(unsigned char bus, unsigned char dev_fn, | ||
232 | unsigned char offset, unsigned short val) | ||
233 | { | ||
234 | uint temp; | ||
235 | ushort *sp; | ||
236 | |||
237 | if ((bus > 7) || (dev_fn > 127)) | ||
238 | return DEVICE_NOT_FOUND; | ||
239 | |||
240 | qs_pci_read_config_dword(bus, dev_fn, offset, &temp); | ||
241 | |||
242 | offset ^= 0x02; | ||
243 | sp = ((ushort *)&temp) + ((offset >> 1) & 1); | ||
244 | *sp = val; | ||
245 | |||
246 | if (bus == 0) | ||
247 | *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); | ||
248 | else | ||
249 | *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); | ||
250 | *QS_CONFIG_DATA = temp; | ||
251 | |||
252 | return SUCCESSFUL; | ||
253 | } | ||
254 | |||
255 | int qs_pci_write_config_dword(unsigned char bus, unsigned char dev_fn, | ||
256 | unsigned char offset, unsigned int val) | ||
257 | { | ||
258 | if ((bus > 7) || (dev_fn > 127)) | ||
259 | return DEVICE_NOT_FOUND; | ||
260 | |||
261 | if (bus == 0) | ||
262 | *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); | ||
263 | else | ||
264 | *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); | ||
265 | *(unsigned int *)QS_CONFIG_DATA = val; | ||
266 | |||
267 | return SUCCESSFUL; | ||
268 | } | ||
269 | |||
diff --git a/arch/ppc/boot/simple/relocate.S b/arch/ppc/boot/simple/relocate.S new file mode 100644 index 000000000000..555a216ccc49 --- /dev/null +++ b/arch/ppc/boot/simple/relocate.S | |||
@@ -0,0 +1,216 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/relocate.S | ||
3 | * | ||
4 | * This is the common part of the loader relocation and initialization | ||
5 | * process. All of the board/processor specific initialization is | ||
6 | * done before we get here. | ||
7 | * | ||
8 | * Author: Tom Rini | ||
9 | * trini@mvista.com | ||
10 | * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others). | ||
11 | * | ||
12 | * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under | ||
13 | * the terms of the GNU General Public License version 2. This program | ||
14 | * is licensed "as is" without any warranty of any kind, whether express | ||
15 | * or implied. | ||
16 | */ | ||
17 | |||
18 | #include <linux/config.h> | ||
19 | #include <asm/cache.h> | ||
20 | #include <asm/ppc_asm.h> | ||
21 | |||
22 | #define GETSYM(reg, sym) \ | ||
23 | lis reg, sym@h; ori reg, reg, sym@l | ||
24 | |||
25 | .text | ||
26 | /* We get called from the early initialization code. | ||
27 | * Register 3 has the address where we were loaded, | ||
28 | * Register 4 contains any residual data passed from the | ||
29 | * boot rom. | ||
30 | */ | ||
31 | .globl relocate | ||
32 | relocate: | ||
33 | /* Save r3, r4 for later. | ||
34 | * The r8/r11 are legacy registers so I don't have to | ||
35 | * rewrite the code below :-). | ||
36 | */ | ||
37 | mr r8, r3 | ||
38 | mr r11, r4 | ||
39 | |||
40 | /* compute the size of the whole image in words. */ | ||
41 | GETSYM(r4,start) | ||
42 | GETSYM(r5,end) | ||
43 | |||
44 | addi r5,r5,3 /* round up */ | ||
45 | sub r5,r5,r4 /* end - start */ | ||
46 | srwi r5,r5,2 | ||
47 | mr r7,r5 /* Save for later use. */ | ||
48 | |||
49 | /* | ||
50 | * Check if we need to relocate ourselves to the link addr or were | ||
51 | * we loaded there to begin with. | ||
52 | */ | ||
53 | cmpw cr0,r3,r4 | ||
54 | beq start_ldr /* If 0, we don't need to relocate */ | ||
55 | |||
56 | /* Move this code somewhere safe. This is max(load + size, end) | ||
57 | * r8 == load address | ||
58 | */ | ||
59 | GETSYM(r4, start) | ||
60 | GETSYM(r5, end) | ||
61 | |||
62 | sub r6,r5,r4 | ||
63 | add r6,r8,r6 /* r6 == phys(load + size) */ | ||
64 | |||
65 | cmpw r5,r6 | ||
66 | bgt 1f | ||
67 | b 2f | ||
68 | 1: | ||
69 | mr r6, r5 | ||
70 | 2: | ||
71 | /* dest is in r6 */ | ||
72 | /* Ensure alignment --- this code is precautionary */ | ||
73 | addi r6,r6,4 | ||
74 | li r5,0x0003 | ||
75 | andc r6,r6,r5 | ||
76 | |||
77 | /* Find physical address and size of do_relocate */ | ||
78 | GETSYM(r5, __relocate_start) | ||
79 | GETSYM(r4, __relocate_end) | ||
80 | GETSYM(r3, start) | ||
81 | |||
82 | /* Size to copy */ | ||
83 | sub r4,r4,r5 | ||
84 | srwi r4,r4,2 | ||
85 | |||
86 | /* Src addr to copy (= __relocate_start - start + where_loaded) */ | ||
87 | sub r3,r5,r3 | ||
88 | add r5,r8,r3 | ||
89 | |||
90 | /* Save dest */ | ||
91 | mr r3, r6 | ||
92 | |||
93 | /* Do the copy */ | ||
94 | mtctr r4 | ||
95 | 3: lwz r4,0(r5) | ||
96 | stw r4,0(r3) | ||
97 | addi r3,r3,4 | ||
98 | addi r5,r5,4 | ||
99 | bdnz 3b | ||
100 | |||
101 | GETSYM(r4, __relocate_start) | ||
102 | GETSYM(r5, do_relocate) | ||
103 | |||
104 | sub r4,r5,r4 /* Get entry point for do_relocate in */ | ||
105 | add r6,r6,r4 /* relocated section */ | ||
106 | |||
107 | /* This will return to the relocated do_relocate */ | ||
108 | mtlr r6 | ||
109 | b flush_instruction_cache | ||
110 | |||
111 | .section ".relocate_code","xa" | ||
112 | |||
113 | do_relocate: | ||
114 | /* We have 2 cases --- start < load, or start > load | ||
115 | * This determines whether we copy from the end, or the start. | ||
116 | * Its easier to have 2 loops than to have paramaterised | ||
117 | * loops. Sigh. | ||
118 | */ | ||
119 | li r6,0 /* Clear checksum */ | ||
120 | mtctr r7 /* Setup for a loop */ | ||
121 | |||
122 | GETSYM(r4, start) | ||
123 | mr r3,r8 /* Get the load addr */ | ||
124 | |||
125 | cmpw cr0,r4,r3 /* If we need to copy from the end, do so */ | ||
126 | bgt do_relocate_from_end | ||
127 | |||
128 | do_relocate_from_start: | ||
129 | 1: lwz r5,0(r3) /* Load and decrement */ | ||
130 | stw r5,0(r4) /* Store and decrement */ | ||
131 | addi r3,r3,4 | ||
132 | addi r4,r4,4 | ||
133 | xor r6,r6,r5 /* Update checksum */ | ||
134 | bdnz 1b /* Are we done? */ | ||
135 | b do_relocate_out /* Finished */ | ||
136 | |||
137 | do_relocate_from_end: | ||
138 | GETSYM(r3, end) | ||
139 | slwi r4,r7,2 | ||
140 | add r4,r8,r4 /* Get the physical end */ | ||
141 | 1: lwzu r5,-4(r4) | ||
142 | stwu r5, -4(r3) | ||
143 | xor r6,r6,r5 | ||
144 | bdnz 1b | ||
145 | |||
146 | do_relocate_out: | ||
147 | GETSYM(r3,start_ldr) | ||
148 | mtlr r3 /* Easiest way to do an absolute jump */ | ||
149 | /* Some boards don't boot up with the I-cache enabled. Do that | ||
150 | * now because the decompress runs much faster that way. | ||
151 | * As a side effect, we have to ensure the data cache is not enabled | ||
152 | * so we can access the serial I/O without trouble. | ||
153 | */ | ||
154 | b flush_instruction_cache | ||
155 | |||
156 | .previous | ||
157 | |||
158 | start_ldr: | ||
159 | /* Clear all of BSS and set up stack for C calls */ | ||
160 | lis r3,edata@h | ||
161 | ori r3,r3,edata@l | ||
162 | lis r4,end@h | ||
163 | ori r4,r4,end@l | ||
164 | subi r3,r3,4 | ||
165 | subi r4,r4,4 | ||
166 | li r0,0 | ||
167 | 50: stwu r0,4(r3) | ||
168 | cmpw cr0,r3,r4 | ||
169 | bne 50b | ||
170 | 90: mr r9,r1 /* Save old stack pointer (in case it matters) */ | ||
171 | lis r1,.stack@h | ||
172 | ori r1,r1,.stack@l | ||
173 | addi r1,r1,4096*2 | ||
174 | subi r1,r1,256 | ||
175 | li r2,0x000F /* Mask pointer to 16-byte boundary */ | ||
176 | andc r1,r1,r2 | ||
177 | |||
178 | /* | ||
179 | * Exec kernel loader | ||
180 | */ | ||
181 | mr r3,r8 /* Load point */ | ||
182 | mr r4,r7 /* Program length */ | ||
183 | mr r5,r6 /* Checksum */ | ||
184 | mr r6,r11 /* Residual data */ | ||
185 | mr r7,r25 /* Validated OFW interface */ | ||
186 | bl load_kernel | ||
187 | |||
188 | /* | ||
189 | * Make sure the kernel knows we don't have things set in | ||
190 | * registers. -- Tom | ||
191 | */ | ||
192 | li r4,0 | ||
193 | li r5,0 | ||
194 | li r6,0 | ||
195 | |||
196 | /* | ||
197 | * Start at the begining. | ||
198 | */ | ||
199 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
200 | li r9,0xc | ||
201 | mtlr r9 | ||
202 | /* tell kernel we're prep, by putting 0xdeadc0de at KERNELLOAD, | ||
203 | * and tell the kernel to start on the 4th instruction since we | ||
204 | * overwrite the first 3 sometimes (which are 'nop'). | ||
205 | */ | ||
206 | lis r10,0xdeadc0de@h | ||
207 | ori r10,r10,0xdeadc0de@l | ||
208 | li r9,0 | ||
209 | stw r10,0(r9) | ||
210 | #else | ||
211 | li r9,0 | ||
212 | mtlr r9 | ||
213 | #endif | ||
214 | blr | ||
215 | |||
216 | .comm .stack,4096*2,4 | ||
diff --git a/arch/ppc/boot/simple/rw4/ppc_40x.h b/arch/ppc/boot/simple/rw4/ppc_40x.h new file mode 100644 index 000000000000..561fb26f5a93 --- /dev/null +++ b/arch/ppc/boot/simple/rw4/ppc_40x.h | |||
@@ -0,0 +1,664 @@ | |||
1 | /*----------------------------------------------------------------------------+ | ||
2 | | This source code has been made available to you by IBM on an AS-IS | ||
3 | | basis. Anyone receiving this source is licensed under IBM | ||
4 | | copyrights to use it in any way he or she deems fit, including | ||
5 | | copying it, modifying it, compiling it, and redistributing it either | ||
6 | | with or without modifications. No license under IBM patents or | ||
7 | | patent applications is to be implied by the copyright license. | ||
8 | | | ||
9 | | Any user of this software should understand that IBM cannot provide | ||
10 | | technical support for this software and will not be responsible for | ||
11 | | any consequences resulting from the use of this software. | ||
12 | | | ||
13 | | Any person who transfers this source code or any derivative work | ||
14 | | must include the IBM copyright notice, this paragraph, and the | ||
15 | | preceding two paragraphs in the transferred software. | ||
16 | | | ||
17 | | COPYRIGHT I B M CORPORATION 1997 | ||
18 | | LICENSED MATERIAL - PROGRAM PROPERTY OF I B M | ||
19 | +----------------------------------------------------------------------------*/ | ||
20 | /*----------------------------------------------------------------------------+ | ||
21 | | Author: Tony J. Cerreto | ||
22 | | Component: Assembler include file. | ||
23 | | File: ppc_40x.h | ||
24 | | Purpose: Include file containing PPC DCR defines. | ||
25 | | | ||
26 | | Changes: | ||
27 | | Date Author Comment | ||
28 | | --------- ------ -------------------------------------------------------- | ||
29 | | 01-Mar-00 tjc Created | ||
30 | +----------------------------------------------------------------------------*/ | ||
31 | /* added by linguohui*/ | ||
32 | #define MW | ||
33 | /*----------------------------------------------------------------------------+ | ||
34 | | PPC Special purpose registers Numbers | ||
35 | +----------------------------------------------------------------------------*/ | ||
36 | #define ccr0 0x3b3 /* core configuration reg */ | ||
37 | #define ctr 0x009 /* count register */ | ||
38 | #define ctrreg 0x009 /* count register */ | ||
39 | #define dbcr0 0x3f2 /* debug control register 0 */ | ||
40 | #define dbcr1 0x3bd /* debug control register 1 */ | ||
41 | #define dbsr 0x3f0 /* debug status register */ | ||
42 | #define dccr 0x3fa /* data cache control reg. */ | ||
43 | #define dcwr 0x3ba /* data cache write-thru reg */ | ||
44 | #define dear 0x3d5 /* data exception address reg */ | ||
45 | #define esr 0x3d4 /* exception syndrome register */ | ||
46 | #define evpr 0x3d6 /* exception vector prefix reg */ | ||
47 | #define iccr 0x3fb /* instruction cache cntrl re */ | ||
48 | #define icdbdr 0x3d3 /* instr cache dbug data reg */ | ||
49 | #define lrreg 0x008 /* link register */ | ||
50 | #define pid 0x3b1 /* process id reg */ | ||
51 | #define pit 0x3db /* programmable interval time */ | ||
52 | #define pvr 0x11f /* processor version register */ | ||
53 | #define sgr 0x3b9 /* storage guarded reg */ | ||
54 | #define sler 0x3bb /* storage little endian reg */ | ||
55 | #define sprg0 0x110 /* special general purpose 0 */ | ||
56 | #define sprg1 0x111 /* special general purpose 1 */ | ||
57 | #define sprg2 0x112 /* special general purpose 2 */ | ||
58 | #define sprg3 0x113 /* special general purpose 3 */ | ||
59 | #define sprg4 0x114 /* special general purpose 4 */ | ||
60 | #define sprg5 0x115 /* special general purpose 5 */ | ||
61 | #define sprg6 0x116 /* special general purpose 6 */ | ||
62 | #define sprg7 0x117 /* special general purpose 7 */ | ||
63 | #define srr0 0x01a /* save/restore register 0 */ | ||
64 | #define srr1 0x01b /* save/restore register 1 */ | ||
65 | #define srr2 0x3de /* save/restore register 2 */ | ||
66 | #define srr3 0x3df /* save/restore register 3 */ | ||
67 | #define tbhi 0x11D | ||
68 | #define tblo 0x11C | ||
69 | #define tcr 0x3da /* timer control register */ | ||
70 | #define tsr 0x3d8 /* timer status register */ | ||
71 | #define xerreg 0x001 /* fixed point exception */ | ||
72 | #define xer 0x001 /* fixed point exception */ | ||
73 | #define zpr 0x3b0 /* zone protection reg */ | ||
74 | |||
75 | /*----------------------------------------------------------------------------+ | ||
76 | | Decompression Controller | ||
77 | +----------------------------------------------------------------------------*/ | ||
78 | #define kiar 0x014 /* Decompression cntl addr reg */ | ||
79 | #define kidr 0x015 /* Decompression cntl data reg */ | ||
80 | #define kitor0 0x00 /* index table origin Reg 0 */ | ||
81 | #define kitor1 0x01 /* index table origin Reg 1 */ | ||
82 | #define kitor2 0x02 /* index table origin Reg 2 */ | ||
83 | #define kitor3 0x03 /* index table origin Reg 3 */ | ||
84 | #define kaddr0 0x04 /* addr decode Definition Reg 0 */ | ||
85 | #define kaddr1 0x05 /* addr decode Definition Reg 1 */ | ||
86 | #define kconf 0x40 /* Decompression cntl config reg */ | ||
87 | #define kid 0x41 /* Decompression cntl id reg */ | ||
88 | #define kver 0x42 /* Decompression cntl ver number */ | ||
89 | #define kpear 0x50 /* bus error addr reg (PLB) */ | ||
90 | #define kbear 0x51 /* bus error addr reg (DCP-EBC) */ | ||
91 | #define kesr0 0x52 /* bus error status reg 0 */ | ||
92 | |||
93 | /*----------------------------------------------------------------------------+ | ||
94 | | Romeo Specific Device Control Register Numbers. | ||
95 | +----------------------------------------------------------------------------*/ | ||
96 | #ifndef VESTA | ||
97 | #define cdbcr 0x3d7 /* cache debug cntrl reg */ | ||
98 | |||
99 | #define a_latcnt 0x1a9 /* PLB Latency count */ | ||
100 | #define a_tgval 0x1ac /* tone generation value */ | ||
101 | #define a_plb_pr 0x1bf /* PLB priority */ | ||
102 | |||
103 | #define cic_sel1 0x031 /* select register 1 */ | ||
104 | #define cic_sel2 0x032 /* select register 2 */ | ||
105 | |||
106 | #define clkgcrst 0x122 /* chip reset register */ | ||
107 | |||
108 | #define cp_cpmsr 0x100 /*rstatus register */ | ||
109 | #define cp_cpmer 0x101 /* enable register */ | ||
110 | |||
111 | #define dcp_kiar 0x190 /* indirect address register */ | ||
112 | #define dcp_kidr 0x191 /* indirect data register */ | ||
113 | |||
114 | #define hsmc_mcgr 0x1c0 /* HSMC global register */ | ||
115 | #define hsmc_mcbesr 0x1c1 /* bus error status register */ | ||
116 | #define hsmc_mcbear 0x1c2 /* bus error address register*/ | ||
117 | #define hsmc_mcbr0 0x1c4 /* SDRAM sub-ctrl bank reg 0 */ | ||
118 | #define hsmc_mccr0 0x1c5 /* SDRAM sub-ctrl ctrl reg 0 */ | ||
119 | #define hsmc_mcbr1 0x1c7 /* SDRAM sub-ctrl bank reg 1 */ | ||
120 | #define hsmc_mccr1 0x1c8 /* SDRAM sub-ctrl ctrl reg 1 */ | ||
121 | #define hsmc_sysr 0x1d1 /* system register */ | ||
122 | #define hsmc_data 0x1d2 /* data register */ | ||
123 | #define hsmc_mccrr 0x1d3 /* refresh register */ | ||
124 | |||
125 | #define ocm_pbar 0x1E0 /* base address register */ | ||
126 | |||
127 | #define plb0_pacr0 0x057 /* PLB arbiter control reg */ | ||
128 | #define plb1_pacr1 0x067 /* PLB arbiter control reg */ | ||
129 | |||
130 | #define v_displb 0x157 /* set left border of display*/ | ||
131 | #define v_disptb 0x158 /* top border of display */ | ||
132 | #define v_osd_la 0x159 /* first link address for OSD*/ | ||
133 | #define v_ptsdlta 0x15E /* PTS delta register */ | ||
134 | #define v_v0base 0x16C /* base mem add for VBI-0 */ | ||
135 | #define v_v1base 0x16D /* base mem add for VBI-1 */ | ||
136 | #define v_osbase 0x16E /* base mem add for OSD data */ | ||
137 | #endif | ||
138 | |||
139 | /*----------------------------------------------------------------------------+ | ||
140 | | Vesta Device Control Register Numbers. | ||
141 | +----------------------------------------------------------------------------*/ | ||
142 | /*----------------------------------------------------------------------------+ | ||
143 | | Cross bar switch. | ||
144 | +----------------------------------------------------------------------------*/ | ||
145 | #define cbs0_cr 0x010 /* CBS configuration register */ | ||
146 | |||
147 | /*----------------------------------------------------------------------------+ | ||
148 | | DCR external master (DCRX). | ||
149 | +----------------------------------------------------------------------------*/ | ||
150 | #define dcrx0_icr 0x020 /* internal control register */ | ||
151 | #define dcrx0_isr 0x021 /* internal status register */ | ||
152 | #define dcrx0_ecr 0x022 /* external control register */ | ||
153 | #define dcrx0_esr 0x023 /* external status register */ | ||
154 | #define dcrx0_tar 0x024 /* target address register */ | ||
155 | #define dcrx0_tdr 0x025 /* target data register */ | ||
156 | #define dcrx0_igr 0x026 /* interrupt generation register */ | ||
157 | #define dcrx0_bcr 0x027 /* buffer control register */ | ||
158 | |||
159 | /*----------------------------------------------------------------------------+ | ||
160 | | Chip interconnect configuration. | ||
161 | +----------------------------------------------------------------------------*/ | ||
162 | #define cic0_cr 0x030 /* CIC control register */ | ||
163 | #define cic0_vcr 0x033 /* video macro control reg */ | ||
164 | #define cic0_sel3 0x035 /* select register 3 */ | ||
165 | |||
166 | /*----------------------------------------------------------------------------+ | ||
167 | | Chip interconnect configuration. | ||
168 | +----------------------------------------------------------------------------*/ | ||
169 | #define sgpo0_sgpO 0x036 /* simplified GPIO output */ | ||
170 | #define sgpo0_gpod 0x037 /* simplified GPIO open drain */ | ||
171 | #define sgpo0_gptc 0x038 /* simplified GPIO tristate cntl */ | ||
172 | #define sgpo0_gpi 0x039 /* simplified GPIO input */ | ||
173 | |||
174 | /*----------------------------------------------------------------------------+ | ||
175 | | Universal interrupt controller. | ||
176 | +----------------------------------------------------------------------------*/ | ||
177 | #define uic0_sr 0x040 /* status register */ | ||
178 | #define uic0_srs 0x041 /* status register set */ | ||
179 | #define uic0_er 0x042 /* enable register */ | ||
180 | #define uic0_cr 0x043 /* critical register */ | ||
181 | #define uic0_pr 0x044 /* parity register */ | ||
182 | #define uic0_tr 0x045 /* triggering register */ | ||
183 | #define uic0_msr 0x046 /* masked status register */ | ||
184 | #define uic0_vr 0x047 /* vector register */ | ||
185 | #define uic0_vcr 0x048 /* enable config register */ | ||
186 | |||
187 | /*----------------------------------------------------------------------------+ | ||
188 | | PLB 0 and 1. | ||
189 | +----------------------------------------------------------------------------*/ | ||
190 | #define pb0_pesr 0x054 /* PLB error status reg 0 */ | ||
191 | #define pb0_pesrs 0x055 /* PLB error status reg 0 set */ | ||
192 | #define pb0_pear 0x056 /* PLB error address reg */ | ||
193 | |||
194 | #define pb1_pesr 0x064 /* PLB error status reg 1 */ | ||
195 | #define pb1_pesrs 0x065 /* PLB error status reg 1 set */ | ||
196 | #define pb1_pear 0x066 /* PLB error address reg */ | ||
197 | |||
198 | /*----------------------------------------------------------------------------+ | ||
199 | | EBIU DCR registers. | ||
200 | +----------------------------------------------------------------------------*/ | ||
201 | #define ebiu0_brcrh0 0x070 /* bus region register 0 high */ | ||
202 | #define ebiu0_brcrh1 0x071 /* bus region register 1 high */ | ||
203 | #define ebiu0_brcrh2 0x072 /* bus region register 2 high */ | ||
204 | #define ebiu0_brcrh3 0x073 /* bus region register 3 high */ | ||
205 | #define ebiu0_brcrh4 0x074 /* bus region register 4 high */ | ||
206 | #define ebiu0_brcrh5 0x075 /* bus region register 5 high */ | ||
207 | #define ebiu0_brcrh6 0x076 /* bus region register 6 high */ | ||
208 | #define ebiu0_brcrh7 0x077 /* bus region register 7 high */ | ||
209 | #define ebiu0_brcr0 0x080 /* bus region register 0 */ | ||
210 | #define ebiu0_brcr1 0x081 /* bus region register 1 */ | ||
211 | #define ebiu0_brcr2 0x082 /* bus region register 2 */ | ||
212 | #define ebiu0_brcr3 0x083 /* bus region register 3 */ | ||
213 | #define ebiu0_brcr4 0x084 /* bus region register 4 */ | ||
214 | #define ebiu0_brcr5 0x085 /* bus region register 5 */ | ||
215 | #define ebiu0_brcr6 0x086 /* bus region register 6 */ | ||
216 | #define ebiu0_brcr7 0x087 /* bus region register 7 */ | ||
217 | #define ebiu0_bear 0x090 /* bus error address register */ | ||
218 | #define ebiu0_besr 0x091 /* bus error syndrome reg */ | ||
219 | #define ebiu0_besr0s 0x093 /* bus error syndrome reg */ | ||
220 | #define ebiu0_biucr 0x09a /* bus interface control reg */ | ||
221 | |||
222 | /*----------------------------------------------------------------------------+ | ||
223 | | OPB bridge. | ||
224 | +----------------------------------------------------------------------------*/ | ||
225 | #define opbw0_gesr 0x0b0 /* error status reg */ | ||
226 | #define opbw0_gesrs 0x0b1 /* error status reg */ | ||
227 | #define opbw0_gear 0x0b2 /* error address reg */ | ||
228 | |||
229 | /*----------------------------------------------------------------------------+ | ||
230 | | DMA. | ||
231 | +----------------------------------------------------------------------------*/ | ||
232 | #define dma0_cr0 0x0c0 /* DMA channel control reg 0 */ | ||
233 | #define dma0_ct0 0x0c1 /* DMA count register 0 */ | ||
234 | #define dma0_da0 0x0c2 /* DMA destination addr reg 0 */ | ||
235 | #define dma0_sa0 0x0c3 /* DMA source addr register 0 */ | ||
236 | #define dma0_cc0 0x0c4 /* DMA chained count 0 */ | ||
237 | #define dma0_cr1 0x0c8 /* DMA channel control reg 1 */ | ||
238 | #define dma0_ct1 0x0c9 /* DMA count register 1 */ | ||
239 | #define dma0_da1 0x0ca /* DMA destination addr reg 1 */ | ||
240 | #define dma0_sa1 0x0cb /* DMA source addr register 1 */ | ||
241 | #define dma0_cc1 0x0cc /* DMA chained count 1 */ | ||
242 | #define dma0_cr2 0x0d0 /* DMA channel control reg 2 */ | ||
243 | #define dma0_ct2 0x0d1 /* DMA count register 2 */ | ||
244 | #define dma0_da2 0x0d2 /* DMA destination addr reg 2 */ | ||
245 | #define dma0_sa2 0x0d3 /* DMA source addr register 2 */ | ||
246 | #define dma0_cc2 0x0d4 /* DMA chained count 2 */ | ||
247 | #define dma0_cr3 0x0d8 /* DMA channel control reg 3 */ | ||
248 | #define dma0_ct3 0x0d9 /* DMA count register 3 */ | ||
249 | #define dma0_da3 0x0da /* DMA destination addr reg 3 */ | ||
250 | #define dma0_sa3 0x0db /* DMA source addr register 3 */ | ||
251 | #define dma0_cc3 0x0dc /* DMA chained count 3 */ | ||
252 | #define dma0_sr 0x0e0 /* DMA status register */ | ||
253 | #define dma0_srs 0x0e1 /* DMA status register */ | ||
254 | #define dma0_s1 0x031 /* DMA select1 register */ | ||
255 | #define dma0_s2 0x032 /* DMA select2 register */ | ||
256 | |||
257 | /*---------------------------------------------------------------------------+ | ||
258 | | Clock and power management. | ||
259 | +----------------------------------------------------------------------------*/ | ||
260 | #define cpm0_fr 0x102 /* force register */ | ||
261 | |||
262 | /*----------------------------------------------------------------------------+ | ||
263 | | Serial Clock Control. | ||
264 | +----------------------------------------------------------------------------*/ | ||
265 | #define ser0_ccr 0x120 /* serial clock control register */ | ||
266 | |||
267 | /*----------------------------------------------------------------------------+ | ||
268 | | Audio Clock Control. | ||
269 | +----------------------------------------------------------------------------*/ | ||
270 | #define aud0_apcr 0x121 /* audio clock ctrl register */ | ||
271 | |||
272 | /*----------------------------------------------------------------------------+ | ||
273 | | DENC. | ||
274 | +----------------------------------------------------------------------------*/ | ||
275 | #define denc0_idr 0x130 /* DENC ID register */ | ||
276 | #define denc0_cr1 0x131 /* control register 1 */ | ||
277 | #define denc0_rr1 0x132 /* microvision 1 (reserved 1) */ | ||
278 | #define denc0_cr2 0x133 /* control register 2 */ | ||
279 | #define denc0_rr2 0x134 /* microvision 2 (reserved 2) */ | ||
280 | #define denc0_rr3 0x135 /* microvision 3 (reserved 3) */ | ||
281 | #define denc0_rr4 0x136 /* microvision 4 (reserved 4) */ | ||
282 | #define denc0_rr5 0x137 /* microvision 5 (reserved 5) */ | ||
283 | #define denc0_ccdr 0x138 /* closed caption data */ | ||
284 | #define denc0_cccr 0x139 /* closed caption control */ | ||
285 | #define denc0_trr 0x13A /* teletext request register */ | ||
286 | #define denc0_tosr 0x13B /* teletext odd field line se */ | ||
287 | #define denc0_tesr 0x13C /* teletext even field line s */ | ||
288 | #define denc0_rlsr 0x13D /* RGB rhift left register */ | ||
289 | #define denc0_vlsr 0x13E /* video level shift register */ | ||
290 | #define denc0_vsr 0x13F /* video scaling register */ | ||
291 | |||
292 | /*----------------------------------------------------------------------------+ | ||
293 | | Video decoder. Suspect 0x179, 0x169, 0x16a, 0x152 (rc). | ||
294 | +----------------------------------------------------------------------------*/ | ||
295 | #define vid0_ccntl 0x140 /* control decoder operation */ | ||
296 | #define vid0_cmode 0x141 /* video operational mode */ | ||
297 | #define vid0_sstc0 0x142 /* STC high order bits 31:0 */ | ||
298 | #define vid0_sstc1 0x143 /* STC low order bit 32 */ | ||
299 | #define vid0_spts0 0x144 /* PTS high order bits 31:0 */ | ||
300 | #define vid0_spts1 0x145 /* PTS low order bit 32 */ | ||
301 | #define vid0_fifo 0x146 /* FIFO data port */ | ||
302 | #define vid0_fifos 0x147 /* FIFO status */ | ||
303 | #define vid0_cmd 0x148 /* send command to decoder */ | ||
304 | #define vid0_cmdd 0x149 /* port for command params */ | ||
305 | #define vid0_cmdst 0x14A /* command status */ | ||
306 | #define vid0_cmdad 0x14B /* command address */ | ||
307 | #define vid0_procia 0x14C /* instruction store */ | ||
308 | #define vid0_procid 0x14D /* data port for I_Store */ | ||
309 | #define vid0_osdm 0x151 /* OSD mode control */ | ||
310 | #define vid0_hosti 0x152 /* base interrupt register */ | ||
311 | #define vid0_mask 0x153 /* interrupt mask register */ | ||
312 | #define vid0_dispm 0x154 /* operational mode for Disp */ | ||
313 | #define vid0_dispd 0x155 /* setting for 'Sync' delay */ | ||
314 | #define vid0_vbctl 0x156 /* VBI */ | ||
315 | #define vid0_ttxctl 0x157 /* teletext control */ | ||
316 | #define vid0_disptb 0x158 /* display left/top border */ | ||
317 | #define vid0_osdgla 0x159 /* Graphics plane link addr */ | ||
318 | #define vid0_osdila 0x15A /* Image plane link addr */ | ||
319 | #define vid0_rbthr 0x15B /* rate buffer threshold */ | ||
320 | #define vid0_osdcla 0x15C /* Cursor link addr */ | ||
321 | #define vid0_stcca 0x15D /* STC common address */ | ||
322 | #define vid0_ptsctl 0x15F /* PTS Control */ | ||
323 | #define vid0_wprot 0x165 /* write protect for I_Store */ | ||
324 | #define vid0_vcqa 0x167 /* video clip queued block Ad */ | ||
325 | #define vid0_vcql 0x168 /* video clip queued block Le */ | ||
326 | #define vid0_blksz 0x169 /* block size bytes for copy op */ | ||
327 | #define vid0_srcad 0x16a /* copy source address bits 6-31 */ | ||
328 | #define vid0_udbas 0x16B /* base mem add for user data */ | ||
329 | #define vid0_vbibas 0x16C /* base mem add for VBI 0/1 */ | ||
330 | #define vid0_osdibas 0x16D /* Image plane base address */ | ||
331 | #define vid0_osdgbas 0x16E /* Graphic plane base address */ | ||
332 | #define vid0_rbbase 0x16F /* base mem add for video buf */ | ||
333 | #define vid0_dramad 0x170 /* DRAM address */ | ||
334 | #define vid0_dramdt 0x171 /* data port for DRAM access */ | ||
335 | #define vid0_dramcs 0x172 /* DRAM command and statusa */ | ||
336 | #define vid0_vcwa 0x173 /* v clip work address */ | ||
337 | #define vid0_vcwl 0x174 /* v clip work length */ | ||
338 | #define vid0_mseg0 0x175 /* segment address 0 */ | ||
339 | #define vid0_mseg1 0x176 /* segment address 1 */ | ||
340 | #define vid0_mseg2 0x177 /* segment address 2 */ | ||
341 | #define vid0_mseg3 0x178 /* segment address 3 */ | ||
342 | #define vid0_fbbase 0x179 /* frame buffer base memory */ | ||
343 | #define vid0_osdcbas 0x17A /* Cursor base addr */ | ||
344 | #define vid0_lboxtb 0x17B /* top left border */ | ||
345 | #define vid0_trdly 0x17C /* transparency gate delay */ | ||
346 | #define vid0_sbord 0x17D /* left/top small pict. bord. */ | ||
347 | #define vid0_zoffs 0x17E /* hor/ver zoom window */ | ||
348 | #define vid0_rbsz 0x17F /* rate buffer size read */ | ||
349 | |||
350 | /*----------------------------------------------------------------------------+ | ||
351 | | Transport demultiplexer. | ||
352 | +----------------------------------------------------------------------------*/ | ||
353 | #define xpt0_lr 0x180 /* demux location register */ | ||
354 | #define xpt0_data 0x181 /* demux data register */ | ||
355 | #define xpt0_ir 0x182 /* demux interrupt register */ | ||
356 | |||
357 | #define xpt0_config1 0x0000 /* configuration 1 */ | ||
358 | #define xpt0_control1 0x0001 /* control 1 */ | ||
359 | #define xpt0_festat 0x0002 /* Front-end status */ | ||
360 | #define xpt0_feimask 0x0003 /* Front_end interrupt Mask */ | ||
361 | #define xpt0_ocmcnfg 0x0004 /* OCM Address */ | ||
362 | #define xpt0_settapi 0x0005 /* Set TAP Interrupt */ | ||
363 | |||
364 | #define xpt0_pcrhi 0x0010 /* PCR High */ | ||
365 | #define xpt0_pcrlow 0x0011 /* PCR Low */ | ||
366 | #define xpt0_lstchi 0x0012 /* Latched STC High */ | ||
367 | #define xpt0_lstclow 0x0013 /* Latched STC Low */ | ||
368 | #define xpt0_stchi 0x0014 /* STC High */ | ||
369 | #define xpt0_stclow 0x0015 /* STC Low */ | ||
370 | #define xpt0_pwm 0x0016 /* PWM */ | ||
371 | #define xpt0_pcrstct 0x0017 /* PCR-STC Threshold */ | ||
372 | #define xpt0_pcrstcd 0x0018 /* PCR-STC Delta */ | ||
373 | #define xpt0_stccomp 0x0019 /* STC Compare */ | ||
374 | #define xpt0_stccmpd 0x001a /* STC Compare Disarm */ | ||
375 | |||
376 | #define xpt0_dsstat 0x0048 /* Descrambler Status */ | ||
377 | #define xpt0_dsimask 0x0049 /* Descrambler Interrupt Mask */ | ||
378 | |||
379 | #define xpt0_vcchng 0x01f0 /* Video Channel Change */ | ||
380 | #define xpt0_acchng 0x01f1 /* Audio Channel Change */ | ||
381 | #define xpt0_axenable 0x01fe /* Aux PID Enables */ | ||
382 | #define xpt0_pcrpid 0x01ff /* PCR PID */ | ||
383 | |||
384 | #define xpt0_config2 0x1000 /* Configuration 2 */ | ||
385 | #define xpt0_pbuflvl 0x1002 /* Packet Buffer Level */ | ||
386 | #define xpt0_intmask 0x1003 /* Interrupt Mask */ | ||
387 | #define xpt0_plbcnfg 0x1004 /* PLB Configuration */ | ||
388 | |||
389 | #define xpt0_qint 0x1010 /* Queues Interrupts */ | ||
390 | #define xpt0_qintmsk 0x1011 /* Queues Interrupts Mask */ | ||
391 | #define xpt0_astatus 0x1012 /* Audio Status */ | ||
392 | #define xpt0_aintmask 0x1013 /* Audio Interrupt Mask */ | ||
393 | #define xpt0_vstatus 0x1014 /* Video Status */ | ||
394 | #define xpt0_vintmask 0x1015 /* Video Interrupt Mask */ | ||
395 | |||
396 | #define xpt0_qbase 0x1020 /* Queue Base */ | ||
397 | #define xpt0_bucketq 0x1021 /* Bucket Queue */ | ||
398 | #define xpt0_qstops 0x1024 /* Queue Stops */ | ||
399 | #define xpt0_qresets 0x1025 /* Queue Resets */ | ||
400 | #define xpt0_sfchng 0x1026 /* Section Filter Change */ | ||
401 | |||
402 | /*----------------------------------------------------------------------------+ | ||
403 | | Audio decoder. Suspect 0x1ad, 0x1b4, 0x1a3, 0x1a5 (read/write status) | ||
404 | +----------------------------------------------------------------------------*/ | ||
405 | #define aud0_ctrl0 0x1a0 /* control 0 */ | ||
406 | #define aud0_ctrl1 0x1a1 /* control 1 */ | ||
407 | #define aud0_ctrl2 0x1a2 /* control 2 */ | ||
408 | #define aud0_cmd 0x1a3 /* command register */ | ||
409 | #define aud0_isr 0x1a4 /* interrupt status register */ | ||
410 | #define aud0_imr 0x1a5 /* interrupt mask register */ | ||
411 | #define aud0_dsr 0x1a6 /* decoder status register */ | ||
412 | #define aud0_stc 0x1a7 /* system time clock */ | ||
413 | #define aud0_csr 0x1a8 /* channel status register */ | ||
414 | #define aud0_lcnt 0x1a9 /* queued address register 2 */ | ||
415 | #define aud0_pts 0x1aa /* presentation time stamp */ | ||
416 | #define aud0_tgctrl 0x1ab /* tone generation control */ | ||
417 | #define aud0_qlr2 0x1ac /* queued length register 2 */ | ||
418 | #define aud0_auxd 0x1ad /* aux data */ | ||
419 | #define aud0_strmid 0x1ae /* stream ID */ | ||
420 | #define aud0_qar 0x1af /* queued address register */ | ||
421 | #define aud0_dsps 0x1b0 /* DSP status */ | ||
422 | #define aud0_qlr 0x1b1 /* queued len address */ | ||
423 | #define aud0_dspc 0x1b2 /* DSP control */ | ||
424 | #define aud0_wlr2 0x1b3 /* working length register 2 */ | ||
425 | #define aud0_instd 0x1b4 /* instruction download */ | ||
426 | #define aud0_war 0x1b5 /* working address register */ | ||
427 | #define aud0_seg1 0x1b6 /* segment 1 base register */ | ||
428 | #define aud0_seg2 0x1b7 /* segment 2 base register */ | ||
429 | #define aud0_avf 0x1b9 /* audio att value front */ | ||
430 | #define aud0_avr 0x1ba /* audio att value rear */ | ||
431 | #define aud0_avc 0x1bb /* audio att value center */ | ||
432 | #define aud0_seg3 0x1bc /* segment 3 base register */ | ||
433 | #define aud0_offset 0x1bd /* offset address */ | ||
434 | #define aud0_wrl 0x1be /* working length register */ | ||
435 | #define aud0_war2 0x1bf /* working address register 2 */ | ||
436 | |||
437 | /*----------------------------------------------------------------------------+ | ||
438 | | High speed memory controller 0 and 1. | ||
439 | +----------------------------------------------------------------------------*/ | ||
440 | #define hsmc0_gr 0x1e0 /* HSMC global register */ | ||
441 | #define hsmc0_besr 0x1e1 /* bus error status register */ | ||
442 | #define hsmc0_bear 0x1e2 /* bus error address register */ | ||
443 | #define hsmc0_br0 0x1e4 /* SDRAM sub-ctrl bank reg 0 */ | ||
444 | #define hsmc0_cr0 0x1e5 /* SDRAM sub-ctrl ctrl reg 0 */ | ||
445 | #define hsmc0_br1 0x1e7 /* SDRAM sub-ctrl bank reg 1 */ | ||
446 | #define hsmc0_cr1 0x1e8 /* SDRAM sub-ctrl ctrl reg 1 */ | ||
447 | #define hsmc0_sysr 0x1f1 /* system register */ | ||
448 | #define hsmc0_data 0x1f2 /* data register */ | ||
449 | #define hsmc0_crr 0x1f3 /* refresh register */ | ||
450 | |||
451 | #define hsmc1_gr 0x1c0 /* HSMC global register */ | ||
452 | #define hsmc1_besr 0x1c1 /* bus error status register */ | ||
453 | #define hsmc1_bear 0x1c2 /* bus error address register */ | ||
454 | #define hsmc1_br0 0x1c4 /* SDRAM sub-ctrl bank reg 0 */ | ||
455 | #define hsmc1_cr0 0x1c5 /* SDRAM sub-ctrl ctrl reg 0 */ | ||
456 | #define hsmc1_br1 0x1c7 /* SDRAM sub-ctrl bank reg 1 */ | ||
457 | #define hsmc1_cr1 0x1c8 /* SDRAM sub-ctrl ctrl reg 1 */ | ||
458 | #define hsmc1_sysr 0x1d1 /* system register */ | ||
459 | #define hsmc1_data 0x1d2 /* data register */ | ||
460 | #define hsmc1_crr 0x1d3 /* refresh register */ | ||
461 | |||
462 | /*----------------------------------------------------------------------------+ | ||
463 | | Machine State Register bit definitions. | ||
464 | +----------------------------------------------------------------------------*/ | ||
465 | #define msr_ape 0x00100000 | ||
466 | #define msr_apa 0x00080000 | ||
467 | #define msr_we 0x00040000 | ||
468 | #define msr_ce 0x00020000 | ||
469 | #define msr_ile 0x00010000 | ||
470 | #define msr_ee 0x00008000 | ||
471 | #define msr_pr 0x00004000 | ||
472 | #define msr_me 0x00001000 | ||
473 | #define msr_de 0x00000200 | ||
474 | #define msr_ir 0x00000020 | ||
475 | #define msr_dr 0x00000010 | ||
476 | #define msr_le 0x00000001 | ||
477 | |||
478 | /*----------------------------------------------------------------------------+ | ||
479 | | Used during interrupt processing. | ||
480 | +----------------------------------------------------------------------------*/ | ||
481 | #define stack_reg_image_size 160 | ||
482 | |||
483 | /*----------------------------------------------------------------------------+ | ||
484 | | Function prolog definition and other Metaware (EABI) defines. | ||
485 | +----------------------------------------------------------------------------*/ | ||
486 | #ifdef MW | ||
487 | |||
488 | #define r0 0 | ||
489 | #define r1 1 | ||
490 | #define r2 2 | ||
491 | #define r3 3 | ||
492 | #define r4 4 | ||
493 | #define r5 5 | ||
494 | #define r6 6 | ||
495 | #define r7 7 | ||
496 | #define r8 8 | ||
497 | #define r9 9 | ||
498 | #define r10 10 | ||
499 | #define r11 11 | ||
500 | #define r12 12 | ||
501 | #define r13 13 | ||
502 | #define r14 14 | ||
503 | #define r15 15 | ||
504 | #define r16 16 | ||
505 | #define r17 17 | ||
506 | #define r18 18 | ||
507 | #define r19 19 | ||
508 | #define r20 20 | ||
509 | #define r21 21 | ||
510 | #define r22 22 | ||
511 | #define r23 23 | ||
512 | #define r24 24 | ||
513 | #define r25 25 | ||
514 | #define r26 26 | ||
515 | #define r27 27 | ||
516 | #define r28 28 | ||
517 | #define r29 29 | ||
518 | #define r30 30 | ||
519 | #define r31 31 | ||
520 | |||
521 | #define cr0 0 | ||
522 | #define cr1 1 | ||
523 | #define cr2 2 | ||
524 | #define cr3 3 | ||
525 | #define cr4 4 | ||
526 | #define cr5 5 | ||
527 | #define cr6 6 | ||
528 | #define cr7 7 | ||
529 | |||
530 | #define function_prolog(func_name) .text; \ | ||
531 | .align 2; \ | ||
532 | .globl func_name; \ | ||
533 | func_name: | ||
534 | #define function_epilog(func_name) .type func_name,@function; \ | ||
535 | .size func_name,.-func_name | ||
536 | |||
537 | #define function_call(func_name) bl func_name | ||
538 | |||
539 | #define stack_frame_min 8 | ||
540 | #define stack_frame_bc 0 | ||
541 | #define stack_frame_lr 4 | ||
542 | #define stack_neg_off 0 | ||
543 | |||
544 | #endif | ||
545 | |||
546 | /*----------------------------------------------------------------------------+ | ||
547 | | Function prolog definition and other DIAB (Elf) defines. | ||
548 | +----------------------------------------------------------------------------*/ | ||
549 | #ifdef ELF_DIAB | ||
550 | |||
551 | fprolog: macro f_name | ||
552 | .text | ||
553 | .align 2 | ||
554 | .globl f_name | ||
555 | f_name: | ||
556 | endm | ||
557 | |||
558 | fepilog: macro f_name | ||
559 | .type f_name,@function | ||
560 | .size f_name,.-f_name | ||
561 | endm | ||
562 | |||
563 | #define function_prolog(func_name) fprolog func_name | ||
564 | #define function_epilog(func_name) fepilog func_name | ||
565 | #define function_call(func_name) bl func_name | ||
566 | |||
567 | #define stack_frame_min 8 | ||
568 | #define stack_frame_bc 0 | ||
569 | #define stack_frame_lr 4 | ||
570 | #define stack_neg_off 0 | ||
571 | |||
572 | #endif | ||
573 | |||
574 | /*----------------------------------------------------------------------------+ | ||
575 | | Function prolog definition and other Xlc (XCOFF) defines. | ||
576 | +----------------------------------------------------------------------------*/ | ||
577 | #ifdef XCOFF | ||
578 | |||
579 | .machine "403ga" | ||
580 | |||
581 | #define r0 0 | ||
582 | #define r1 1 | ||
583 | #define r2 2 | ||
584 | #define r3 3 | ||
585 | #define r4 4 | ||
586 | #define r5 5 | ||
587 | #define r6 6 | ||
588 | #define r7 7 | ||
589 | #define r8 8 | ||
590 | #define r9 9 | ||
591 | #define r10 10 | ||
592 | #define r11 11 | ||
593 | #define r12 12 | ||
594 | #define r13 13 | ||
595 | #define r14 14 | ||
596 | #define r15 15 | ||
597 | #define r16 16 | ||
598 | #define r17 17 | ||
599 | #define r18 18 | ||
600 | #define r19 19 | ||
601 | #define r20 20 | ||
602 | #define r21 21 | ||
603 | #define r22 22 | ||
604 | #define r23 23 | ||
605 | #define r24 24 | ||
606 | #define r25 25 | ||
607 | #define r26 26 | ||
608 | #define r27 27 | ||
609 | #define r28 28 | ||
610 | #define r29 29 | ||
611 | #define r30 30 | ||
612 | #define r31 31 | ||
613 | |||
614 | #define cr0 0 | ||
615 | #define cr1 1 | ||
616 | #define cr2 2 | ||
617 | #define cr3 3 | ||
618 | #define cr4 4 | ||
619 | #define cr5 5 | ||
620 | #define cr6 6 | ||
621 | #define cr7 7 | ||
622 | |||
623 | #define function_prolog(func_name) .csect .func_name[PR]; \ | ||
624 | .globl .func_name[PR]; \ | ||
625 | func_name: | ||
626 | |||
627 | #define function_epilog(func_name) .toc; \ | ||
628 | .csect func_name[DS]; \ | ||
629 | .globl func_name[DS]; \ | ||
630 | .long .func_name[PR]; \ | ||
631 | .long TOC[tc0] | ||
632 | |||
633 | #define function_call(func_name) .extern .func_name[PR]; \ | ||
634 | stw r2,stack_frame_toc(r1); \ | ||
635 | mfspr r2,sprg0; \ | ||
636 | bl .func_name[PR]; \ | ||
637 | lwz r2,stack_frame_toc(r1) | ||
638 | |||
639 | #define stack_frame_min 56 | ||
640 | #define stack_frame_bc 0 | ||
641 | #define stack_frame_lr 8 | ||
642 | #define stack_frame_toc 20 | ||
643 | #define stack_neg_off 276 | ||
644 | |||
645 | #endif | ||
646 | #define function_prolog(func_name) .text; \ | ||
647 | .align 2; \ | ||
648 | .globl func_name; \ | ||
649 | func_name: | ||
650 | #define function_epilog(func_name) .type func_name,@function; \ | ||
651 | .size func_name,.-func_name | ||
652 | |||
653 | #define function_call(func_name) bl func_name | ||
654 | |||
655 | /*----------------------------------------------------------------------------+ | ||
656 | | Function prolog definition for GNU | ||
657 | +----------------------------------------------------------------------------*/ | ||
658 | #ifdef _GNU_TOOL | ||
659 | |||
660 | #define function_prolog(func_name) .globl func_name; \ | ||
661 | func_name: | ||
662 | #define function_epilog(func_name) | ||
663 | |||
664 | #endif | ||
diff --git a/arch/ppc/boot/simple/rw4/rw4_init.S b/arch/ppc/boot/simple/rw4/rw4_init.S new file mode 100644 index 000000000000..b1061962e46b --- /dev/null +++ b/arch/ppc/boot/simple/rw4/rw4_init.S | |||
@@ -0,0 +1,78 @@ | |||
1 | #define VESTA | ||
2 | #include "ppc_40x.h" | ||
3 | # | ||
4 | .align 2 | ||
5 | .text | ||
6 | # | ||
7 | # added by linguohui | ||
8 | .extern initb_ebiu0, initb_config, hdw_init_finish | ||
9 | .extern initb_hsmc0, initb_hsmc1, initb_cache | ||
10 | # end added | ||
11 | .globl HdwInit | ||
12 | # | ||
13 | HdwInit: | ||
14 | # | ||
15 | #-----------------------------------------------------------------------* | ||
16 | # If we are not executing from the FLASH get out * | ||
17 | #-----------------------------------------------------------------------* | ||
18 | # SAW keep this or comment out a la Hawthorne? | ||
19 | # r3 contains NIP when used with Linux | ||
20 | # rlwinm r28, r3, 8, 24, 31 # if MSB == 0xFF -> FLASH address | ||
21 | # cmpwi r28, 0xff | ||
22 | # bne locn01 | ||
23 | # | ||
24 | # | ||
25 | #------------------------------------------------------------------------ | ||
26 | # Init_cpu. Bank registers are setup for the IBM STB. | ||
27 | #------------------------------------------------------------------------ | ||
28 | # | ||
29 | # Setup processor core clock to be driven off chip. This is GPI4 bit | ||
30 | # twenty. Setup Open Drain, Output Select, Three-State Control, and | ||
31 | # Three-State Select registers. | ||
32 | # | ||
33 | |||
34 | |||
35 | pb0pesr = 0x054 | ||
36 | pb0pear = 0x056 | ||
37 | |||
38 | mflr r30 | ||
39 | |||
40 | #----------------------------------------------------------------------------- | ||
41 | # Vectors will be at 0x1F000000 | ||
42 | # Dummy Machine check handler just does RFI before true handler gets installed | ||
43 | #----------------------------------------------------------------------------- | ||
44 | #if 1 /* xuwentao added*/ | ||
45 | #ifdef SDRAM16MB | ||
46 | lis r10,0x0000 | ||
47 | addi r10,r10,0x0000 | ||
48 | #else | ||
49 | lis r10,0x1F00 | ||
50 | addi r10,r10,0x0000 | ||
51 | #endif | ||
52 | |||
53 | mtspr evpr,r10 #EVPR: 0x0 or 0x1f000000 depending | ||
54 | isync # on SDRAM memory model used. | ||
55 | |||
56 | lis r10,0xFFFF # clear PB0_PESR because some | ||
57 | ori r10,r10,0xFFFF # transitions from flash,changed by linguohui | ||
58 | mtdcr pb0pesr,r10 # to load RAM image via RiscWatch | ||
59 | lis r10,0x0000 # cause PB0_PESR machine checks | ||
60 | mtdcr pb0pear,r10 | ||
61 | addis r10,r10,0x0000 # clear the | ||
62 | mtxer r10 # XER just in case... | ||
63 | #endif /* xuwentao*/ | ||
64 | |||
65 | bl initb_ebiu0 # init EBIU | ||
66 | |||
67 | bl initb_config # config PPC and board | ||
68 | |||
69 | |||
70 | |||
71 | |||
72 | #------------------------------------------------------------------------ | ||
73 | # EVPR setup moved to top of this function. | ||
74 | #------------------------------------------------------------------------ | ||
75 | # | ||
76 | mtlr r30 | ||
77 | blr | ||
78 | .end | ||
diff --git a/arch/ppc/boot/simple/rw4/rw4_init_brd.S b/arch/ppc/boot/simple/rw4/rw4_init_brd.S new file mode 100644 index 000000000000..386afdaad6c7 --- /dev/null +++ b/arch/ppc/boot/simple/rw4/rw4_init_brd.S | |||
@@ -0,0 +1,1125 @@ | |||
1 | /*----------------------------------------------------------------------------+ | ||
2 | | This source code has been made available to you by IBM on an AS-IS | ||
3 | | basis. Anyone receiving this source is licensed under IBM | ||
4 | | copyrights to use it in any way he or she deems fit, including | ||
5 | | copying it, modifying it, compiling it, and redistributing it either | ||
6 | | with or without modifications. No license under IBM patents or | ||
7 | | patent applications is to be implied by the copyright license. | ||
8 | | | ||
9 | | Any user of this software should understand that IBM cannot provide | ||
10 | | technical support for this software and will not be responsible for | ||
11 | | any consequences resulting from the use of this software. | ||
12 | | | ||
13 | | Any person who transfers this source code or any derivative work | ||
14 | | must include the IBM copyright notice, this paragraph, and the | ||
15 | | preceding two paragraphs in the transferred software. | ||
16 | | | ||
17 | | COPYRIGHT I B M CORPORATION 1997 | ||
18 | | LICENSED MATERIAL - PROGRAM PROPERTY OF I B M | ||
19 | +----------------------------------------------------------------------------*/ | ||
20 | /*----------------------------------------------------------------------------+ | ||
21 | | Author: Tony J. Cerreto | ||
22 | | Component: BSPS | ||
23 | | File: init_brd.s | ||
24 | | Purpose: Vesta Evaluation Board initialization subroutines. The following | ||
25 | | routines are available: | ||
26 | | 1. INITB_EBIU0: Initialize EBIU0. | ||
27 | | 2. INITB_CONFIG: Configure board. | ||
28 | | 3. INITB_HSMC0: Initialize HSMC0 (SDRAM). | ||
29 | | 4. INITB_HSMC1: Initialize HSMC1 (SDRAM). | ||
30 | | 5. INITB_CACHE: Initialize Data and Instruction Cache. | ||
31 | | 6. INITB_DCACHE: Initialize Data Cache. | ||
32 | | 7. INITB_ICACHE: Initialize Instruction Cache. | ||
33 | | 8. INITB_GET_CSPD: Get CPU Speed (Bus Speed and Processor Speed) | ||
34 | | | ||
35 | | Changes: | ||
36 | | Date: Author Comment: | ||
37 | | --------- ------ -------- | ||
38 | | 01-Mar-00 tjc Created | ||
39 | | 04-Mar-00 jfh Modified CIC_SEL3_VAL to support 1284 (Mux3 & GPIO 21-28) | ||
40 | | 04-Mar-00 jfh Modified XILINIX Reg 0 to support 1284 (Mux3 & GPIO 21-28) | ||
41 | | 04-Mar-00 jfh Modified XILINIX Reg 1 to support 1284 (Mux3 & GPIO 21-28) | ||
42 | | 04-Mar-00 jfh Modified XILINIX Reg 4 to support 1284 (Mux3 & GPIO 21-28) | ||
43 | | 19-May-00 rlb Relcoated HSMC0 to 0x1F000000 to support 32MB of contiguous | ||
44 | | SDRAM space. Changed cache ctl regs to reflect this. | ||
45 | | 22-May-00 tjc Changed initb_get_cspd interface and eliminated | ||
46 | | initb_get_bspd routines. | ||
47 | | 26-May-00 tjc Added two nop instructions after all mtxxx/mfxxx | ||
48 | | instructions due to PPC405 bug. | ||
49 | +----------------------------------------------------------------------------*/ | ||
50 | #define VESTA | ||
51 | #include "ppc_40x.h" | ||
52 | #include "stb.h" | ||
53 | |||
54 | /*----------------------------------------------------------------------------+ | ||
55 | | BOARD CONFIGURATION DEFINES | ||
56 | +----------------------------------------------------------------------------*/ | ||
57 | #define CBS0_CR_VAL 0x00000002 /* CBS control reg value */ | ||
58 | #define CIC0_CR_VAL 0xD0800448 /* CIC control reg value */ | ||
59 | #define CIC0_SEL3_VAL 0x11500000 /* CIC select 3 reg value */ | ||
60 | #define CIC0_VCR_VAL 0x00631700 /* CIC video cntl reg value */ | ||
61 | |||
62 | /*----------------------------------------------------------------------------+ | ||
63 | | EBIU0 BANK REGISTERS DEFINES | ||
64 | +----------------------------------------------------------------------------*/ | ||
65 | #define EBIU0_BRCRH0_VAL 0x00000000 /* BR High 0 (Extension Reg)*/ | ||
66 | #define EBIU0_BRCRH1_VAL 0x00000000 /* BR High 1 (Extension Reg)*/ | ||
67 | #define EBIU0_BRCRH2_VAL 0x40000000 /* BR High 2 (Extension Reg)*/ | ||
68 | #define EBIU0_BRCRH3_VAL 0x40000000 /* BR High 3 (Extension Reg)*/ | ||
69 | #define EBIU0_BRCRH4_VAL 0x00000000 /* BR High 4 (Extension Reg)*/ | ||
70 | #define EBIU0_BRCRH5_VAL 0x00000000 /* BR High 5 (Extension Reg)*/ | ||
71 | #define EBIU0_BRCRH6_VAL 0x00000000 /* BR High 6 (Extension Reg)*/ | ||
72 | #define EBIU0_BRCRH7_VAL 0x40000000 /* BR High 7 (Extension Reg)*/ | ||
73 | |||
74 | #define EBIU0_BRCR0_VAL 0xFC58BFFE /* BR 0: 16 bit Flash 4 MB */ | ||
75 | #define EBIU0_BRCR1_VAL 0xFF00BFFE /* BR 1: Ext Connector 1 MB */ | ||
76 | #if 1 | ||
77 | #define EBIU0_BRCR2_VAL 0x207CFFBE /* BR 2: Xilinx 8 MB */ | ||
78 | /* twt == 0x3f */ | ||
79 | #else | ||
80 | #define EBIU0_BRCR2_VAL 0x207CCFBE /* BR 2: Xilinx 8 MB */ | ||
81 | /* twt == 0x0f */ | ||
82 | #endif | ||
83 | #define EBIU0_BRCR3_VAL 0x407CBFBE /* BR 3: IDE Drive 8 MB */ | ||
84 | #define EBIU0_BRCR4_VAL 0xFF00BFFF /* BR 4: Disabled. 0 MB */ | ||
85 | #define EBIU0_BRCR5_VAL 0xFF00BFFF /* BR 5: Disabled. 0 MB */ | ||
86 | #define EBIU0_BRCR6_VAL 0xFF00BFFF /* BR 6: Disabled. 0 MB */ | ||
87 | #define EBIU0_BRCR7_VAL 0xCE3F0003 /* BR 7: Line Mode DMA 2 MB */ | ||
88 | |||
89 | /*----------------------------------------------------------------------------+ | ||
90 | | GPIO DEFINES | ||
91 | +----------------------------------------------------------------------------*/ | ||
92 | #define STB_GPIO0_OUTPUT (STB_GPIO0_BASE_ADDRESS+ 0x00) | ||
93 | #define STB_GPIO0_TC (STB_GPIO0_BASE_ADDRESS+ 0x04) | ||
94 | #define STB_GPIO0_OS_0_31 (STB_GPIO0_BASE_ADDRESS+ 0x08) | ||
95 | #define STB_GPIO0_OS_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x0C) | ||
96 | #define STB_GPIO0_TS_0_31 (STB_GPIO0_BASE_ADDRESS+ 0x10) | ||
97 | #define STB_GPIO0_TS_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x14) | ||
98 | #define STB_GPIO0_OD (STB_GPIO0_BASE_ADDRESS+ 0x18) | ||
99 | #define STB_GPIO0_INPUT (STB_GPIO0_BASE_ADDRESS+ 0x1C) | ||
100 | #define STB_GPIO0_R1 (STB_GPIO0_BASE_ADDRESS+ 0x20) | ||
101 | #define STB_GPIO0_R2 (STB_GPIO0_BASE_ADDRESS+ 0x24) | ||
102 | #define STB_GPIO0_R3 (STB_GPIO0_BASE_ADDRESS+ 0x28) | ||
103 | #define STB_GPIO0_IS_1_0_31 (STB_GPIO0_BASE_ADDRESS+ 0x30) | ||
104 | #define STB_GPIO0_IS_1_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x34) | ||
105 | #define STB_GPIO0_IS_2_0_31 (STB_GPIO0_BASE_ADDRESS+ 0x38) | ||
106 | #define STB_GPIO0_IS_2_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x3C) | ||
107 | #define STB_GPIO0_IS_3_0_31 (STB_GPIO0_BASE_ADDRESS+ 0x40) | ||
108 | #define STB_GPIO0_IS_3_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x44) | ||
109 | #define STB_GPIO0_SS_1 (STB_GPIO0_BASE_ADDRESS+ 0x50) | ||
110 | #define STB_GPIO0_SS_2 (STB_GPIO0_BASE_ADDRESS+ 0x54) | ||
111 | #define STB_GPIO0_SS_3 (STB_GPIO0_BASE_ADDRESS+ 0x58) | ||
112 | |||
113 | #define GPIO0_TC_VAL 0x0C020004 /* three-state control val */ | ||
114 | #define GPIO0_OS_0_31_VAL 0x51A00004 /* output select 0-31 val */ | ||
115 | #define GPIO0_OS_32_63_VAL 0x0000002F /* output select 32-63 val */ | ||
116 | #define GPIO0_TS_0_31_VAL 0x51A00000 /* three-state sel 0-31 val*/ | ||
117 | #define GPIO0_TS_32_63_VAL 0x0000000F /* three-state sel 32-63 val*/ | ||
118 | #define GPIO0_OD_VAL 0xC0000004 /* open drain val */ | ||
119 | #define GPIO0_IS_1_0_31_VAL 0x50000151 /* input select 1 0-31 val */ | ||
120 | #define GPIO0_IS_1_32_63_VAL 0x00000000 /* input select 1 32-63 val */ | ||
121 | #define GPIO0_IS_2_0_31_VAL 0x00000000 /* input select 2 0-31 val */ | ||
122 | #define GPIO0_IS_2_32_63_VAL 0x00000000 /* input select 2 32-63 val */ | ||
123 | #define GPIO0_IS_3_0_31_VAL 0x00000440 /* input select 3 0-31 val */ | ||
124 | #define GPIO0_IS_3_32_63_VAL 0x00000000 /* input select 3 32-63 val */ | ||
125 | #define GPIO0_SS_1_VAL 0x00000000 /* sync select 1 val */ | ||
126 | #define GPIO0_SS_2_VAL 0x00000000 /* sync select 2 val */ | ||
127 | #define GPIO0_SS_3_VAL 0x00000000 /* sync select 3 val */ | ||
128 | |||
129 | /*----------------------------------------------------------------------------+ | ||
130 | | XILINX DEFINES | ||
131 | +----------------------------------------------------------------------------*/ | ||
132 | #define STB_XILINX_LED (STB_FPGA_BASE_ADDRESS+ 0x0100) | ||
133 | #define STB_XILINX1_REG0 (STB_FPGA_BASE_ADDRESS+ 0x40000) | ||
134 | #define STB_XILINX1_REG1 (STB_FPGA_BASE_ADDRESS+ 0x40002) | ||
135 | #define STB_XILINX1_REG2 (STB_FPGA_BASE_ADDRESS+ 0x40004) | ||
136 | #define STB_XILINX1_REG3 (STB_FPGA_BASE_ADDRESS+ 0x40006) | ||
137 | #define STB_XILINX1_REG4 (STB_FPGA_BASE_ADDRESS+ 0x40008) | ||
138 | #define STB_XILINX1_REG5 (STB_FPGA_BASE_ADDRESS+ 0x4000A) | ||
139 | #define STB_XILINX1_REG6 (STB_FPGA_BASE_ADDRESS+ 0x4000C) | ||
140 | #define STB_XILINX1_ID (STB_FPGA_BASE_ADDRESS+ 0x4000E) | ||
141 | #define STB_XILINX1_FLUSH (STB_FPGA_BASE_ADDRESS+ 0x4000E) | ||
142 | #define STB_XILINX2_REG0 (STB_FPGA_BASE_ADDRESS+ 0x80000) | ||
143 | #define STB_XILINX2_REG1 (STB_FPGA_BASE_ADDRESS+ 0x80002) | ||
144 | #define STB_XILINX2_REG2 (STB_FPGA_BASE_ADDRESS+ 0x80004) | ||
145 | |||
146 | #define XILINX1_R0_VAL 0x2440 /* Xilinx 1 Register 0 Val */ | ||
147 | #define XILINX1_R1_VAL 0x0025 /* Xilinx 1 Register 1 Val */ | ||
148 | #define XILINX1_R2_VAL 0x0441 /* Xilinx 1 Register 2 Val */ | ||
149 | #define XILINX1_R3_VAL 0x0008 /* Xilinx 1 Register 3 Val */ | ||
150 | #define XILINX1_R4_VAL 0x0100 /* Xilinx 1 Register 4 Val */ | ||
151 | #define XILINX1_R5_VAL 0x6810 /* Xilinx 1 Register 5 Val */ | ||
152 | #define XILINX1_R6_VAL 0x0000 /* Xilinx 1 Register 6 Val */ | ||
153 | #if 0 | ||
154 | #define XILINX2_R0_VAL 0x0008 /* Xilinx 2 Register 0 Val */ | ||
155 | #define XILINX2_R1_VAL 0x0000 /* Xilinx 2 Register 1 Val */ | ||
156 | #else | ||
157 | #define XILINX2_R0_VAL 0x0018 /* disable IBM IrDA RxD */ | ||
158 | #define XILINX2_R1_VAL 0x0008 /* enable SICC MAX chip */ | ||
159 | #endif | ||
160 | #define XILINX2_R2_VAL 0x0000 /* Xilinx 2 Register 2 Val */ | ||
161 | |||
162 | /*----------------------------------------------------------------------------+ | ||
163 | | HSMC BANK REGISTERS DEFINES | ||
164 | +----------------------------------------------------------------------------*/ | ||
165 | #ifdef SDRAM16MB | ||
166 | #define HSMC0_BR0_VAL 0x000D2D55 /* 0x1F000000-007FFFFF R/W */ | ||
167 | #define HSMC0_BR1_VAL 0x008D2D55 /* 0x1F800000-1FFFFFFF R/W */ | ||
168 | #else | ||
169 | #define HSMC0_BR0_VAL 0x1F0D2D55 /* 0x1F000000-007FFFFF R/W */ | ||
170 | #define HSMC0_BR1_VAL 0x1F8D2D55 /* 0x1F800000-1FFFFFFF R/W */ | ||
171 | #endif | ||
172 | #define HSMC1_BR0_VAL 0xA00D2D55 /* 0xA0000000-A07FFFFF R/W */ | ||
173 | #define HSMC1_BR1_VAL 0xA08D2D55 /* 0xA0800000-A0FFFFFF R/W */ | ||
174 | |||
175 | /*----------------------------------------------------------------------------+ | ||
176 | | CACHE DEFINES | ||
177 | +----------------------------------------------------------------------------*/ | ||
178 | #define DCACHE_NLINES 128 /* no. D-cache lines */ | ||
179 | #define DCACHE_NBYTES 32 /* no. bytes/ D-cache line */ | ||
180 | #define ICACHE_NLINES 256 /* no. I-cache lines */ | ||
181 | #define ICACHE_NBYTES 32 /* no. bytes/ I-cache line */ | ||
182 | #ifdef SDRAM16MB | ||
183 | #define DCACHE_ENABLE 0x80000000 /* D-cache regions to enable*/ | ||
184 | #define ICACHE_ENABLE 0x80000001 /* I-cache regions to enable*/ | ||
185 | #else | ||
186 | #define DCACHE_ENABLE 0x18000000 /* D-cache regions to enable*/ | ||
187 | #define ICACHE_ENABLE 0x18000001 /* I-cache regions to enable*/ | ||
188 | #endif | ||
189 | |||
190 | /*----------------------------------------------------------------------------+ | ||
191 | | CPU CORE SPEED CALCULATION DEFINES | ||
192 | +----------------------------------------------------------------------------*/ | ||
193 | #define GCS_LCNT 500000 /* CPU speed loop count */ | ||
194 | #define GCS_TROW_BYTES 8 /* no. bytes in table row */ | ||
195 | #define GCS_CTICK_TOL 100 /* allowable clock tick tol */ | ||
196 | #define GCS_NMULT 4 /* no. of core speed mults */ | ||
197 | |||
198 | /*--------------------------------------------------------------------+ | ||
199 | | No. 13.5Mhz | ||
200 | | Clock Ticks | ||
201 | | based on a | ||
202 | | loop count Bus | ||
203 | | of 100,000 Speed | ||
204 | +--------------------------------------------------------------------*/ | ||
205 | gcs_lookup_table: | ||
206 | .int 50000, 54000000 /* 54.0 Mhz */ | ||
207 | .int 66667, 40500000 /* 40.5 Mhz */ | ||
208 | .int 54545, 49500000 /* 49.5 Mhz */ | ||
209 | .int 46154, 58500000 /* 58.5 Mhz */ | ||
210 | .int 0, 0 /* end of table flag */ | ||
211 | |||
212 | |||
213 | /*****************************************************************************+ | ||
214 | | XXXXXXX XXX XXX XXXXXX XXXXXXX XXXXXX XX XX XX XXXX | ||
215 | | XX X XX XX X XX X XX X XX XX XXX XX XXXX XX | ||
216 | | XX X XXX XX XX X XX XX XXXX XX XX XX XX | ||
217 | | XXXX X XX XXXX XXXXX XX XXXX XX XX XX | ||
218 | | XX X XXX XX XX X XX XX XX XXX XXXXXX XX | ||
219 | | XX X XX XX XX XX X XX XX XX XX XX XX XX XX | ||
220 | | XXXXXXX XXX XXX XXXX XXXXXXX XXX XX XX XX XX XX XXXXXXX | ||
221 | +*****************************************************************************/ | ||
222 | /****************************************************************************** | ||
223 | | | ||
224 | | Routine: INITB_EBIU0. | ||
225 | | | ||
226 | | Purpose: Initialize all the EBIU0 Bank Registers | ||
227 | | Parameters: None. | ||
228 | | Returns: None. | ||
229 | | | ||
230 | ******************************************************************************/ | ||
231 | function_prolog(initb_ebiu0) | ||
232 | /*--------------------------------------------------------------------+ | ||
233 | | Set EBIU0 Bank 0 | ||
234 | +--------------------------------------------------------------------*/ | ||
235 | lis r10,EBIU0_BRCR0_VAL@h | ||
236 | ori r10,r10,EBIU0_BRCR0_VAL@l | ||
237 | mtdcr ebiu0_brcr0,r10 | ||
238 | lis r10,EBIU0_BRCRH0_VAL@h | ||
239 | ori r10,r10,EBIU0_BRCRH0_VAL@l | ||
240 | mtdcr ebiu0_brcrh0,r10 | ||
241 | |||
242 | /*--------------------------------------------------------------------+ | ||
243 | | Set EBIU0 Bank 1 | ||
244 | +--------------------------------------------------------------------*/ | ||
245 | lis r10,EBIU0_BRCR1_VAL@h | ||
246 | ori r10,r10,EBIU0_BRCR1_VAL@l | ||
247 | mtdcr ebiu0_brcr1,r10 | ||
248 | lis r10,EBIU0_BRCRH1_VAL@h | ||
249 | ori r10,r10,EBIU0_BRCRH1_VAL@l | ||
250 | mtdcr ebiu0_brcrh1,r10 | ||
251 | |||
252 | /*--------------------------------------------------------------------+ | ||
253 | | Set EBIU0 Bank 2 | ||
254 | +--------------------------------------------------------------------*/ | ||
255 | lis r10,EBIU0_BRCR2_VAL@h | ||
256 | ori r10,r10,EBIU0_BRCR2_VAL@l | ||
257 | mtdcr ebiu0_brcr2,r10 | ||
258 | lis r10,EBIU0_BRCRH2_VAL@h | ||
259 | ori r10,r10,EBIU0_BRCRH2_VAL@l | ||
260 | mtdcr ebiu0_brcrh2,r10 | ||
261 | |||
262 | /*--------------------------------------------------------------------+ | ||
263 | | Set EBIU0 Bank 3 | ||
264 | +--------------------------------------------------------------------*/ | ||
265 | lis r10,EBIU0_BRCR3_VAL@h | ||
266 | ori r10,r10,EBIU0_BRCR3_VAL@l | ||
267 | mtdcr ebiu0_brcr3,r10 | ||
268 | lis r10,EBIU0_BRCRH3_VAL@h | ||
269 | ori r10,r10,EBIU0_BRCRH3_VAL@l | ||
270 | mtdcr ebiu0_brcrh3,r10 | ||
271 | |||
272 | /*--------------------------------------------------------------------+ | ||
273 | | Set EBIU0 Bank 4 | ||
274 | +--------------------------------------------------------------------*/ | ||
275 | lis r10,EBIU0_BRCR4_VAL@h | ||
276 | ori r10,r10,EBIU0_BRCR4_VAL@l | ||
277 | mtdcr ebiu0_brcr4,r10 | ||
278 | lis r10,EBIU0_BRCRH4_VAL@h | ||
279 | ori r10,r10,EBIU0_BRCRH4_VAL@l | ||
280 | mtdcr ebiu0_brcrh4,r10 | ||
281 | |||
282 | /*--------------------------------------------------------------------+ | ||
283 | | Set EBIU0 Bank 5 | ||
284 | +--------------------------------------------------------------------*/ | ||
285 | lis r10,EBIU0_BRCR5_VAL@h | ||
286 | ori r10,r10,EBIU0_BRCR5_VAL@l | ||
287 | mtdcr ebiu0_brcr5,r10 | ||
288 | lis r10,EBIU0_BRCRH5_VAL@h | ||
289 | ori r10,r10,EBIU0_BRCRH5_VAL@l | ||
290 | mtdcr ebiu0_brcrh5,r10 | ||
291 | |||
292 | /*--------------------------------------------------------------------+ | ||
293 | | Set EBIU0 Bank 6 | ||
294 | +--------------------------------------------------------------------*/ | ||
295 | lis r10,EBIU0_BRCR6_VAL@h | ||
296 | ori r10,r10,EBIU0_BRCR6_VAL@l | ||
297 | mtdcr ebiu0_brcr6,r10 | ||
298 | lis r10,EBIU0_BRCRH6_VAL@h | ||
299 | ori r10,r10,EBIU0_BRCRH6_VAL@l | ||
300 | mtdcr ebiu0_brcrh6,r10 | ||
301 | |||
302 | /*--------------------------------------------------------------------+ | ||
303 | | Set EBIU0 Bank 7 | ||
304 | +--------------------------------------------------------------------*/ | ||
305 | lis r10,EBIU0_BRCR7_VAL@h | ||
306 | ori r10,r10,EBIU0_BRCR7_VAL@l | ||
307 | mtdcr ebiu0_brcr7,r10 | ||
308 | lis r10,EBIU0_BRCRH7_VAL@h | ||
309 | ori r10,r10,EBIU0_BRCRH7_VAL@l | ||
310 | mtdcr ebiu0_brcrh7,r10 | ||
311 | |||
312 | blr | ||
313 | function_epilog(initb_ebiu0) | ||
314 | |||
315 | |||
316 | /****************************************************************************** | ||
317 | | | ||
318 | | Routine: INITB_CONFIG | ||
319 | | | ||
320 | | Purpose: Configure the Vesta Evaluation Board. The following items | ||
321 | | will be configured: | ||
322 | | 1. Cross-Bar Switch. | ||
323 | | 2. Chip Interconnect. | ||
324 | | 3. Clear/reset key PPC registers. | ||
325 | | 4. Xilinx and GPIO Registers. | ||
326 | | | ||
327 | | Returns: None. | ||
328 | | | ||
329 | ******************************************************************************/ | ||
330 | function_prolog(initb_config) | ||
331 | /*--------------------------------------------------------------------+ | ||
332 | | Init CROSS-BAR SWITCH | ||
333 | +--------------------------------------------------------------------*/ | ||
334 | lis r10,CBS0_CR_VAL@h /* r10 <- CBS Cntl Reg val */ | ||
335 | ori r10,r10,CBS0_CR_VAL@l | ||
336 | mtdcr cbs0_cr,r10 | ||
337 | |||
338 | /*--------------------------------------------------------------------+ | ||
339 | | Init Chip-Interconnect (CIC) Registers | ||
340 | +--------------------------------------------------------------------*/ | ||
341 | lis r10,CIC0_CR_VAL@h /* r10 <- CIC Cntl Reg val */ | ||
342 | ori r10,r10,CIC0_CR_VAL@l | ||
343 | mtdcr cic0_cr,r10 | ||
344 | |||
345 | lis r10,CIC0_SEL3_VAL@h /* r10 <- CIC SEL3 Reg val */ | ||
346 | ori r10,r10,CIC0_SEL3_VAL@l | ||
347 | mtdcr cic0_sel3,r10 | ||
348 | |||
349 | lis r10,CIC0_VCR_VAL@h /* r10 <- CIC Vid C-Reg val */ | ||
350 | ori r10,r10,CIC0_VCR_VAL@l | ||
351 | mtdcr cic0_vcr,r10 | ||
352 | |||
353 | /*--------------------------------------------------------------------+ | ||
354 | | Clear SGR and DCWR | ||
355 | +--------------------------------------------------------------------*/ | ||
356 | li r10,0x0000 | ||
357 | mtspr sgr,r10 | ||
358 | mtspr dcwr,r10 | ||
359 | |||
360 | /*--------------------------------------------------------------------+ | ||
361 | | Clear/set up some machine state registers. | ||
362 | +--------------------------------------------------------------------*/ | ||
363 | li r10,0x0000 /* r10 <- 0 */ | ||
364 | mtdcr ebiu0_besr,r10 /* clr Bus Err Syndrome Reg */ | ||
365 | mtspr esr,r10 /* clr Exceptn Syndrome Reg */ | ||
366 | mttcr r10 /* timer control register */ | ||
367 | |||
368 | mtdcr uic0_er,r10 /* disable all interrupts */ | ||
369 | |||
370 | /* UIC_IIC0 | UIC_IIC1 | UIC_U0 | UIC_IR_RCV | UIC_IR_XMIT */ | ||
371 | lis r10, 0x00600e00@h | ||
372 | ori r10,r10,0x00600e00@l | ||
373 | mtdcr uic0_pr,r10 | ||
374 | |||
375 | li r10,0x00000020 /* UIC_EIR1 */ | ||
376 | mtdcr uic0_tr,r10 | ||
377 | |||
378 | lis r10,0xFFFF /* r10 <- 0xFFFFFFFF */ | ||
379 | ori r10,r10,0xFFFF /* */ | ||
380 | mtdbsr r10 /* clear/reset the dbsr */ | ||
381 | mtdcr uic0_sr,r10 /* clear pending interrupts */ | ||
382 | |||
383 | li r10,0x1000 /* set Machine Exception bit*/ | ||
384 | oris r10,r10,0x2 /* set Criticl Exception bit*/ | ||
385 | mtmsr r10 /* change MSR */ | ||
386 | |||
387 | /*--------------------------------------------------------------------+ | ||
388 | | Clear XER. | ||
389 | +--------------------------------------------------------------------*/ | ||
390 | li r10,0x0000 | ||
391 | mtxer r10 | ||
392 | |||
393 | /*--------------------------------------------------------------------+ | ||
394 | | Init GPIO0 Registers | ||
395 | +--------------------------------------------------------------------*/ | ||
396 | lis r10, STB_GPIO0_TC@h /* Three-state control */ | ||
397 | ori r10,r10,STB_GPIO0_TC@l | ||
398 | lis r11, GPIO0_TC_VAL@h | ||
399 | ori r11,r11,GPIO0_TC_VAL@l | ||
400 | stw r11,0(r10) | ||
401 | |||
402 | lis r10, STB_GPIO0_OS_0_31@h /* output select 0-31 */ | ||
403 | ori r10,r10,STB_GPIO0_OS_0_31@l | ||
404 | lis r11, GPIO0_OS_0_31_VAL@h | ||
405 | ori r11,r11,GPIO0_OS_0_31_VAL@l | ||
406 | stw r11,0(r10) | ||
407 | |||
408 | lis r10, STB_GPIO0_OS_32_63@h /* output select 32-63 */ | ||
409 | ori r10,r10,STB_GPIO0_OS_32_63@l | ||
410 | lis r11, GPIO0_OS_32_63_VAL@h | ||
411 | ori r11,r11,GPIO0_OS_32_63_VAL@l | ||
412 | stw r11,0(r10) | ||
413 | |||
414 | lis r10, STB_GPIO0_TS_0_31@h /* three-state select 0-31 */ | ||
415 | ori r10,r10,STB_GPIO0_TS_0_31@l | ||
416 | lis r11, GPIO0_TS_0_31_VAL@h | ||
417 | ori r11,r11,GPIO0_TS_0_31_VAL@l | ||
418 | stw r11,0(r10) | ||
419 | |||
420 | lis r10, STB_GPIO0_TS_32_63@h /* three-state select 32-63 */ | ||
421 | ori r10,r10,STB_GPIO0_TS_32_63@l | ||
422 | lis r11, GPIO0_TS_32_63_VAL@h | ||
423 | ori r11,r11,GPIO0_TS_32_63_VAL@l | ||
424 | stw r11,0(r10) | ||
425 | |||
426 | lis r10, STB_GPIO0_OD@h /* open drain */ | ||
427 | ori r10,r10,STB_GPIO0_OD@l | ||
428 | lis r11, GPIO0_OD_VAL@h | ||
429 | ori r11,r11,GPIO0_OD_VAL@l | ||
430 | stw r11,0(r10) | ||
431 | |||
432 | lis r10, STB_GPIO0_IS_1_0_31@h /* input select 1, 0-31 */ | ||
433 | ori r10,r10,STB_GPIO0_IS_1_0_31@l | ||
434 | lis r11, GPIO0_IS_1_0_31_VAL@h | ||
435 | ori r11,r11,GPIO0_IS_1_0_31_VAL@l | ||
436 | stw r11,0(r10) | ||
437 | |||
438 | lis r10, STB_GPIO0_IS_1_32_63@h /* input select 1, 32-63 */ | ||
439 | ori r10,r10,STB_GPIO0_IS_1_32_63@l | ||
440 | lis r11, GPIO0_IS_1_32_63_VAL@h | ||
441 | ori r11,r11,GPIO0_IS_1_32_63_VAL@l | ||
442 | stw r11,0(r10) | ||
443 | |||
444 | lis r10, STB_GPIO0_IS_2_0_31@h /* input select 2, 0-31 */ | ||
445 | ori r10,r10,STB_GPIO0_IS_2_0_31@l | ||
446 | lis r11, GPIO0_IS_2_0_31_VAL@h | ||
447 | ori r11,r11,GPIO0_IS_2_0_31_VAL@l | ||
448 | stw r11,0(r10) | ||
449 | |||
450 | lis r10, STB_GPIO0_IS_2_32_63@h /* input select 2, 32-63 */ | ||
451 | ori r10,r10,STB_GPIO0_IS_2_32_63@l | ||
452 | lis r11, GPIO0_IS_2_32_63_VAL@h | ||
453 | ori r11,r11,GPIO0_IS_2_32_63_VAL@l | ||
454 | stw r11,0(r10) | ||
455 | |||
456 | lis r10, STB_GPIO0_IS_3_0_31@h /* input select 3, 0-31 */ | ||
457 | ori r10,r10,STB_GPIO0_IS_3_0_31@l | ||
458 | lis r11, GPIO0_IS_3_0_31_VAL@h | ||
459 | ori r11,r11,GPIO0_IS_3_0_31_VAL@l | ||
460 | stw r11,0(r10) | ||
461 | |||
462 | lis r10, STB_GPIO0_IS_3_32_63@h /* input select 3, 32-63 */ | ||
463 | ori r10,r10,STB_GPIO0_IS_3_32_63@l | ||
464 | lis r11, GPIO0_IS_3_32_63_VAL@h | ||
465 | ori r11,r11,GPIO0_IS_3_32_63_VAL@l | ||
466 | stw r11,0(r10) | ||
467 | |||
468 | lis r10, STB_GPIO0_SS_1@h /* sync select 1 */ | ||
469 | ori r10,r10,STB_GPIO0_SS_1@l | ||
470 | lis r11, GPIO0_SS_1_VAL@h | ||
471 | ori r11,r11,GPIO0_SS_1_VAL@l | ||
472 | stw r11,0(r10) | ||
473 | |||
474 | lis r10, STB_GPIO0_SS_2@h /* sync select 2 */ | ||
475 | ori r10,r10,STB_GPIO0_SS_2@l | ||
476 | lis r11, GPIO0_SS_2_VAL@h | ||
477 | ori r11,r11,GPIO0_SS_2_VAL@l | ||
478 | stw r11,0(r10) | ||
479 | |||
480 | lis r10, STB_GPIO0_SS_3@h /* sync select 3 */ | ||
481 | ori r10,r10,STB_GPIO0_SS_3@l | ||
482 | lis r11, GPIO0_SS_3_VAL@h | ||
483 | ori r11,r11,GPIO0_SS_3_VAL@l | ||
484 | stw r11,0(r10) | ||
485 | |||
486 | /*--------------------------------------------------------------------+ | ||
487 | | Init Xilinx #1 Registers | ||
488 | +--------------------------------------------------------------------*/ | ||
489 | lis r10, STB_XILINX1_REG0@h /* init Xilinx1 Reg 0 */ | ||
490 | ori r10,r10,STB_XILINX1_REG0@l | ||
491 | li r11,XILINX1_R0_VAL | ||
492 | sth r11,0(r10) | ||
493 | |||
494 | lis r10, STB_XILINX1_REG1@h /* init Xilinx1 Reg 1 */ | ||
495 | ori r10,r10,STB_XILINX1_REG1@l | ||
496 | li r11,XILINX1_R1_VAL | ||
497 | sth r11,0(r10) | ||
498 | |||
499 | lis r10, STB_XILINX1_REG2@h /* init Xilinx1 Reg 2 */ | ||
500 | ori r10,r10,STB_XILINX1_REG2@l | ||
501 | li r11,XILINX1_R2_VAL | ||
502 | sth r11,0(r10) | ||
503 | |||
504 | lis r10, STB_XILINX1_REG3@h /* init Xilinx1 Reg 3 */ | ||
505 | ori r10,r10,STB_XILINX1_REG3@l | ||
506 | li r11,XILINX1_R3_VAL | ||
507 | sth r11,0(r10) | ||
508 | |||
509 | lis r10, STB_XILINX1_REG4@h /* init Xilinx1 Reg 4 */ | ||
510 | ori r10,r10,STB_XILINX1_REG4@l | ||
511 | li r11,XILINX1_R4_VAL | ||
512 | sth r11,0(r10) | ||
513 | |||
514 | lis r10, STB_XILINX1_REG5@h /* init Xilinx1 Reg 5 */ | ||
515 | ori r10,r10,STB_XILINX1_REG5@l | ||
516 | li r11,XILINX1_R5_VAL | ||
517 | sth r11,0(r10) | ||
518 | |||
519 | lis r10, STB_XILINX1_REG6@h /* init Xilinx1 Reg 6 */ | ||
520 | ori r10,r10,STB_XILINX1_REG6@l | ||
521 | li r11,XILINX1_R6_VAL | ||
522 | sth r11,0(r10) | ||
523 | |||
524 | lis r10, STB_XILINX1_FLUSH@h /* latch registers in Xilinx*/ | ||
525 | ori r10,r10,STB_XILINX1_FLUSH@l | ||
526 | li r11,0x0000 | ||
527 | sth r11,0(r10) | ||
528 | |||
529 | /*--------------------------------------------------------------------+ | ||
530 | | Init Xilinx #2 Registers | ||
531 | +--------------------------------------------------------------------*/ | ||
532 | lis r10, STB_XILINX2_REG0@h /* init Xilinx2 Reg 0 */ | ||
533 | ori r10,r10,STB_XILINX2_REG0@l | ||
534 | li r11,XILINX2_R0_VAL | ||
535 | sth r11,0(r10) | ||
536 | |||
537 | lis r10, STB_XILINX2_REG1@h /* init Xilinx2 Reg 1 */ | ||
538 | ori r10,r10,STB_XILINX2_REG1@l | ||
539 | li r11,XILINX2_R1_VAL | ||
540 | sth r11,0(r10) | ||
541 | |||
542 | lis r10, STB_XILINX2_REG2@h /* init Xilinx2 Reg 2 */ | ||
543 | ori r10,r10,STB_XILINX2_REG2@l | ||
544 | li r11,XILINX2_R2_VAL | ||
545 | sth r11,0(r10) | ||
546 | |||
547 | blr | ||
548 | function_epilog(initb_config) | ||
549 | |||
550 | |||
551 | /****************************************************************************** | ||
552 | | | ||
553 | | Routine: INITB_HSMC0. | ||
554 | | | ||
555 | | Purpose: Initialize the HSMC0 Registers for SDRAM | ||
556 | | Parameters: None. | ||
557 | | Returns: R3 = 0: Successful | ||
558 | | = -1: Unsuccessful, SDRAM did not reset properly. | ||
559 | | | ||
560 | ******************************************************************************/ | ||
561 | function_prolog(initb_hsmc0) | ||
562 | mflr r0 /* Save return addr */ | ||
563 | |||
564 | /*--------------------------------------------------------------------+ | ||
565 | | Set Global SDRAM Controller to recommended default | ||
566 | +--------------------------------------------------------------------*/ | ||
567 | lis r10,0x6C00 | ||
568 | ori r10,r10,0x0000 | ||
569 | mtdcr hsmc0_gr,r10 | ||
570 | |||
571 | /*--------------------------------------------------------------------+ | ||
572 | | Set HSMC0 Data Register to recommended default | ||
573 | +--------------------------------------------------------------------*/ | ||
574 | lis r10,0x0037 | ||
575 | ori r10,r10,0x0000 | ||
576 | mtdcr hsmc0_data,r10 | ||
577 | |||
578 | /*--------------------------------------------------------------------+ | ||
579 | | Init HSMC0 Bank Register 0 | ||
580 | +--------------------------------------------------------------------*/ | ||
581 | lis r10,HSMC0_BR0_VAL@h | ||
582 | ori r10,r10,HSMC0_BR0_VAL@l | ||
583 | mtdcr hsmc0_br0,r10 | ||
584 | |||
585 | /*--------------------------------------------------------------------+ | ||
586 | | Init HSMC0 Bank Register 1 | ||
587 | +--------------------------------------------------------------------*/ | ||
588 | lis r10,HSMC0_BR1_VAL@h | ||
589 | ori r10,r10,HSMC0_BR1_VAL@l | ||
590 | mtdcr hsmc0_br1,r10 | ||
591 | |||
592 | /*--------------------------------------------------------------------+ | ||
593 | | Set HSMC0 Control Reg 0 | ||
594 | +--------------------------------------------------------------------*/ | ||
595 | lis r10,0x8077 /* PRECHARGE ALL DEVICE BKS */ | ||
596 | ori r10,r10,0x0000 | ||
597 | mtdcr hsmc0_cr0,r10 | ||
598 | li r3,0x0000 | ||
599 | bl hsmc_cr_wait /* wait for op completion */ | ||
600 | cmpwi cr0,r3,0x0000 | ||
601 | bne cr0,hsmc0_err | ||
602 | |||
603 | lis r10,0x8078 /* AUTO-REFRESH */ | ||
604 | ori r10,r10,0x0000 | ||
605 | mtdcr hsmc0_cr0,r10 | ||
606 | li r3,0x0000 | ||
607 | bl hsmc_cr_wait /* wait for op completion */ | ||
608 | cmpwi cr0,r3,0x0000 | ||
609 | bne cr0,hsmc0_err | ||
610 | |||
611 | lis r10,0x8070 /* PROG MODE W/DATA REG VAL */ | ||
612 | ori r10,r10,0x8000 | ||
613 | mtdcr hsmc0_cr0,r10 | ||
614 | li r3,0x0000 | ||
615 | bl hsmc_cr_wait /* wait for op completion */ | ||
616 | cmpwi cr0,r3,0x0000 | ||
617 | bne hsmc0_err | ||
618 | |||
619 | /*--------------------------------------------------------------------+ | ||
620 | | Set HSMC0 Control Reg 1 | ||
621 | +--------------------------------------------------------------------*/ | ||
622 | lis r10,0x8077 /* PRECHARGE ALL DEVICE BKS */ | ||
623 | ori r10,r10,0x0000 | ||
624 | mtdcr hsmc0_cr1,r10 | ||
625 | li r3,0x0001 | ||
626 | bl hsmc_cr_wait /* wait for op completion */ | ||
627 | cmpwi cr0,r3,0x0000 | ||
628 | bne cr0,hsmc0_err | ||
629 | |||
630 | lis r10,0x8078 /* AUTO-REFRESH */ | ||
631 | ori r10,r10,0x0000 | ||
632 | mtdcr hsmc0_cr1,r10 | ||
633 | li r3,0x0001 | ||
634 | bl hsmc_cr_wait /* wait for op completion */ | ||
635 | cmpwi cr0,r3,0x0000 | ||
636 | bne cr0,hsmc0_err | ||
637 | |||
638 | lis r10,0x8070 /* PROG MODE W/DATA REG VAL */ | ||
639 | ori r10,r10,0x8000 | ||
640 | mtdcr hsmc0_cr1,r10 | ||
641 | li r3,0x0001 | ||
642 | bl hsmc_cr_wait /* wait for op completion */ | ||
643 | cmpwi cr0,r3,0x0000 | ||
644 | bne cr0,hsmc0_err | ||
645 | |||
646 | /*--------------------------------------------------------------------+ | ||
647 | | Set HSMC0 Refresh Register | ||
648 | +--------------------------------------------------------------------*/ | ||
649 | lis r10,0x0FE1 | ||
650 | ori r10,r10,0x0000 | ||
651 | mtdcr hsmc0_crr,r10 | ||
652 | li r3,0 | ||
653 | |||
654 | hsmc0_err: | ||
655 | mtlr r0 | ||
656 | blr | ||
657 | function_epilog(initb_hsmc0) | ||
658 | |||
659 | |||
660 | /****************************************************************************** | ||
661 | | | ||
662 | | Routine: INITB_HSMC1. | ||
663 | | | ||
664 | | Purpose: Initialize the HSMC1 Registers for SDRAM | ||
665 | | Parameters: None. | ||
666 | | Returns: R3 = 0: Successful | ||
667 | | = -1: Unsuccessful, SDRAM did not reset properly. | ||
668 | | | ||
669 | ******************************************************************************/ | ||
670 | function_prolog(initb_hsmc1) | ||
671 | mflr r0 /* Save return addr */ | ||
672 | |||
673 | /*--------------------------------------------------------------------+ | ||
674 | | Set Global SDRAM Controller to recommended default | ||
675 | +--------------------------------------------------------------------*/ | ||
676 | lis r10,0x6C00 | ||
677 | ori r10,r10,0x0000 | ||
678 | mtdcr hsmc1_gr,r10 | ||
679 | |||
680 | /*--------------------------------------------------------------------+ | ||
681 | | Set HSMC1 Data Register to recommended default | ||
682 | +--------------------------------------------------------------------*/ | ||
683 | lis r10,0x0037 | ||
684 | ori r10,r10,0x0000 | ||
685 | mtdcr hsmc1_data,r10 | ||
686 | |||
687 | /*--------------------------------------------------------------------+ | ||
688 | | Init HSMC1 Bank Register 0 | ||
689 | +--------------------------------------------------------------------*/ | ||
690 | lis r10,HSMC1_BR0_VAL@h | ||
691 | ori r10,r10,HSMC1_BR0_VAL@l | ||
692 | mtdcr hsmc1_br0,r10 | ||
693 | |||
694 | /*--------------------------------------------------------------------+ | ||
695 | | Init HSMC1 Bank Register 1 | ||
696 | +--------------------------------------------------------------------*/ | ||
697 | lis r10,HSMC1_BR1_VAL@h | ||
698 | ori r10,r10,HSMC1_BR1_VAL@l | ||
699 | mtdcr hsmc1_br1,r10 | ||
700 | |||
701 | /*--------------------------------------------------------------------+ | ||
702 | | Set HSMC1 Control Reg 0 | ||
703 | +--------------------------------------------------------------------*/ | ||
704 | lis r10,0x8077 /* PRECHARGE ALL DEVICE BANKS */ | ||
705 | ori r10,r10,0x0000 | ||
706 | mtdcr hsmc1_cr0,r10 | ||
707 | li r3,0x0002 | ||
708 | bl hsmc_cr_wait /* wait for operation completion */ | ||
709 | cmpwi cr0,r3,0x0000 | ||
710 | bne hsmc1_err | ||
711 | |||
712 | lis r10,0x8078 /* AUTO-REFRESH */ | ||
713 | ori r10,r10,0x0000 | ||
714 | mtdcr hsmc1_cr0,r10 | ||
715 | li r3,0x0002 | ||
716 | bl hsmc_cr_wait /* wait for operation completion */ | ||
717 | cmpwi cr0,r3,0x0000 | ||
718 | bne hsmc1_err | ||
719 | |||
720 | lis r10,0x8070 /* PROGRAM MODE W/DATA REG VALUE */ | ||
721 | ori r10,r10,0x8000 | ||
722 | mtdcr hsmc1_cr0,r10 | ||
723 | li r3,0x0002 | ||
724 | bl hsmc_cr_wait /* wait for operation completion */ | ||
725 | cmpwi cr0,r3,0x0000 | ||
726 | bne hsmc1_err | ||
727 | |||
728 | /*--------------------------------------------------------------------+ | ||
729 | | Set HSMC1 Control Reg 1 | ||
730 | +--------------------------------------------------------------------*/ | ||
731 | lis r10,0x8077 /* PRECHARGE ALL DEVICE BKS */ | ||
732 | ori r10,r10,0x0000 | ||
733 | mtdcr hsmc1_cr1,r10 | ||
734 | li r3,0x0003 | ||
735 | bl hsmc_cr_wait /* wait for op completion */ | ||
736 | cmpwi cr0,r3,0x0000 | ||
737 | bne hsmc1_err | ||
738 | |||
739 | lis r10,0x8078 /* AUTO-REFRESH */ | ||
740 | ori r10,r10,0x0000 | ||
741 | mtdcr hsmc1_cr1,r10 | ||
742 | li r3,0x0003 | ||
743 | bl hsmc_cr_wait /* wait for op completion */ | ||
744 | cmpwi cr0,r3,0x0000 | ||
745 | bne hsmc1_err | ||
746 | |||
747 | lis r10,0x8070 /* PROG MODE W/DATA REG VAL */ | ||
748 | ori r10,r10,0x8000 | ||
749 | mtdcr hsmc1_cr1,r10 | ||
750 | li r3,0x0003 | ||
751 | bl hsmc_cr_wait /* wait for op completion */ | ||
752 | cmpwi cr0,r3,0x0000 | ||
753 | bne hsmc1_err | ||
754 | |||
755 | /*--------------------------------------------------------------------+ | ||
756 | | Set HSMC1 Refresh Register | ||
757 | +--------------------------------------------------------------------*/ | ||
758 | lis r10,0x0FE1 | ||
759 | ori r10,r10,0x0000 | ||
760 | mtdcr hsmc1_crr,r10 | ||
761 | xor r3,r3,r3 | ||
762 | |||
763 | hsmc1_err: | ||
764 | mtlr r0 | ||
765 | blr | ||
766 | function_epilog(initb_hsmc1) | ||
767 | |||
768 | |||
769 | /****************************************************************************** | ||
770 | | | ||
771 | | Routine: INITB_CACHE | ||
772 | | | ||
773 | | Purpose: This routine will enable Data and Instruction Cache. | ||
774 | | The Data Cache is an 8K two-way set associative and the | ||
775 | | Instruction Cache is an 16K two-way set associative cache. | ||
776 | | | ||
777 | | Parameters: None. | ||
778 | | | ||
779 | | Returns: None. | ||
780 | | | ||
781 | ******************************************************************************/ | ||
782 | function_prolog(initb_cache) | ||
783 | mflr r0 /* Save return addr */ | ||
784 | |||
785 | bl initb_Dcache /* enable D-Cache */ | ||
786 | bl initb_Icache /* enable I-Cache */ | ||
787 | |||
788 | mtlr r0 | ||
789 | blr | ||
790 | function_epilog(initb_cache) | ||
791 | |||
792 | |||
793 | /****************************************************************************** | ||
794 | | | ||
795 | | Routine: INITB_DCACHE | ||
796 | | | ||
797 | | Purpose: This routine will invalidate all data in the Data Cache and | ||
798 | | then enable D-Cache. If cache is enabled already, the D-Cache | ||
799 | | will be flushed before the data is invalidated. | ||
800 | | | ||
801 | | Parameters: None. | ||
802 | | | ||
803 | | Returns: None. | ||
804 | | | ||
805 | ******************************************************************************/ | ||
806 | function_prolog(initb_Dcache) | ||
807 | /*--------------------------------------------------------------------+ | ||
808 | | Flush Data Cache if enabled | ||
809 | +--------------------------------------------------------------------*/ | ||
810 | mfdccr r10 /* r10 <- DCCR */ | ||
811 | isync /* ensure prev insts done */ | ||
812 | cmpwi r10,0x00 | ||
813 | beq ic_dcinv /* D-cache off, invalidate */ | ||
814 | |||
815 | /*--------------------------------------------------------------------+ | ||
816 | | Data Cache enabled, force known memory addresses to be Cached | ||
817 | +--------------------------------------------------------------------*/ | ||
818 | lis r10,HSMC0_BR0_VAL@h /* r10 <- first memory loc */ | ||
819 | andis. r10,r10,0xFFF0 | ||
820 | li r11,DCACHE_NLINES /* r11 <- # A-way addresses */ | ||
821 | addi r11,r11,DCACHE_NLINES /* r11 <- # B-way addresses */ | ||
822 | mtctr r11 /* set loop counter */ | ||
823 | |||
824 | ic_dcload: | ||
825 | lwz r12,0(r10) /* force cache of address */ | ||
826 | addi r10,r10,DCACHE_NBYTES /* r10 <- next memory loc */ | ||
827 | bdnz ic_dcload | ||
828 | sync /* ensure prev insts done */ | ||
829 | isync | ||
830 | |||
831 | /*--------------------------------------------------------------------+ | ||
832 | | Flush the known memory addresses from Cache | ||
833 | +--------------------------------------------------------------------*/ | ||
834 | lis r10,HSMC0_BR0_VAL@h /* r10 <- first memory loc */ | ||
835 | andis. r10,r10,0xFFF0 | ||
836 | mtctr r11 /* set loop counter */ | ||
837 | |||
838 | ic_dcflush: | ||
839 | dcbf 0,r10 /* flush D-cache line */ | ||
840 | addi r10,r10,DCACHE_NBYTES /* r10 <- next memory loc */ | ||
841 | bdnz ic_dcflush | ||
842 | sync /* ensure prev insts done */ | ||
843 | isync | ||
844 | |||
845 | /*--------------------------------------------------------------------+ | ||
846 | | Disable then invalidate Data Cache | ||
847 | +--------------------------------------------------------------------*/ | ||
848 | li r10,0 /* r10 <- 0 */ | ||
849 | mtdccr r10 /* disable the D-Cache */ | ||
850 | isync /* ensure prev insts done */ | ||
851 | |||
852 | ic_dcinv: | ||
853 | li r10,0 /* r10 <- line address */ | ||
854 | li r11,DCACHE_NLINES /* r11 <- # lines in cache */ | ||
855 | mtctr r11 /* set loop counter */ | ||
856 | |||
857 | ic_dcloop: | ||
858 | dccci 0,r10 /* invalidate A/B cache lns */ | ||
859 | addi r10,r10,DCACHE_NBYTES /* bump to next line */ | ||
860 | bdnz ic_dcloop | ||
861 | sync /* ensure prev insts done */ | ||
862 | isync | ||
863 | |||
864 | /*--------------------------------------------------------------------+ | ||
865 | | Enable Data Cache | ||
866 | +--------------------------------------------------------------------*/ | ||
867 | lis r10,DCACHE_ENABLE@h /* r10 <- D-cache enable msk*/ | ||
868 | ori r10,r10,DCACHE_ENABLE@l | ||
869 | mtdccr r10 | ||
870 | sync /* ensure prev insts done */ | ||
871 | isync | ||
872 | |||
873 | blr | ||
874 | function_epilog(initb_Dcache) | ||
875 | |||
876 | |||
877 | /****************************************************************************** | ||
878 | | | ||
879 | | Routine: INITB_ICACHE | ||
880 | | | ||
881 | | Purpose: This routine will invalidate all data in the Instruction | ||
882 | | Cache then enable I-Cache. | ||
883 | | | ||
884 | | Parameters: None. | ||
885 | | | ||
886 | | Returns: None. | ||
887 | | | ||
888 | ******************************************************************************/ | ||
889 | function_prolog(initb_Icache) | ||
890 | /*--------------------------------------------------------------------+ | ||
891 | | Invalidate Instruction Cache | ||
892 | +--------------------------------------------------------------------*/ | ||
893 | li r10,0 /* r10 <- lines address */ | ||
894 | iccci 0,r10 /* invalidate all I-cache */ | ||
895 | sync /* ensure prev insts done */ | ||
896 | isync | ||
897 | |||
898 | /*--------------------------------------------------------------------+ | ||
899 | | Enable Instruction Cache | ||
900 | +--------------------------------------------------------------------*/ | ||
901 | lis r10,ICACHE_ENABLE@h /* r10 <- I-cache enable msk*/ | ||
902 | ori r10,r10,ICACHE_ENABLE@l | ||
903 | mticcr r10 | ||
904 | sync /* ensure prev insts done */ | ||
905 | isync | ||
906 | |||
907 | blr | ||
908 | function_epilog(initb_Icache) | ||
909 | |||
910 | #if 0 | ||
911 | /****************************************************************************** | ||
912 | | | ||
913 | | Routine: INITB_GET_CSPD | ||
914 | | | ||
915 | | Purpose: Determine the CPU Core Speed. The 13.5 Mhz Time Base | ||
916 | | Counter (TBC) is used to measure a conditional branch | ||
917 | | instruction. | ||
918 | | | ||
919 | | Parameters: R3 = Address of Bus Speed | ||
920 | | R4 = Address of Core Speed | ||
921 | | | ||
922 | | Returns: (R3) = >0: Bus Speed. | ||
923 | | 0: Bus Speed not found in Look-Up Table. | ||
924 | | (R4) = >0: Core Speed. | ||
925 | | 0: Core Speed not found in Look-Up Table. | ||
926 | | | ||
927 | | Note: 1. This routine assumes the bdnz branch instruction takes | ||
928 | | two instruction cycles to complete. | ||
929 | | 2. This routine must be called before interrupts are enabled. | ||
930 | | | ||
931 | ******************************************************************************/ | ||
932 | function_prolog(initb_get_cspd) | ||
933 | mflr r0 /* Save return address */ | ||
934 | /*--------------------------------------------------------------------+ | ||
935 | | Set-up timed loop | ||
936 | +--------------------------------------------------------------------*/ | ||
937 | lis r9,gcs_time_loop@h /* r9 <- addr loop instr */ | ||
938 | ori r9,r9,gcs_time_loop@l | ||
939 | lis r10,GCS_LCNT@h /* r10 <- loop count */ | ||
940 | ori r10,r10,GCS_LCNT@l | ||
941 | mtctr r10 /* ctr <- loop count */ | ||
942 | lis r11,STB_TIMERS_TBC@h /* r11 <- TBC register addr */ | ||
943 | ori r11,r11,STB_TIMERS_TBC@l | ||
944 | li r12,0 /* r12 <- 0 */ | ||
945 | |||
946 | /*--------------------------------------------------------------------+ | ||
947 | | Cache timed-loop instruction | ||
948 | +--------------------------------------------------------------------*/ | ||
949 | icbt 0,r9 | ||
950 | sync | ||
951 | isync | ||
952 | |||
953 | /*--------------------------------------------------------------------+ | ||
954 | | Get number of 13.5 Mhz cycles to execute time-loop | ||
955 | +--------------------------------------------------------------------*/ | ||
956 | stw r12,0(r11) /* reset TBC */ | ||
957 | gcs_time_loop: | ||
958 | bdnz+ gcs_time_loop /* force branch pred taken */ | ||
959 | lwz r5,0(r11) /* r5 <- num 13.5 Mhz ticks */ | ||
960 | li r6,5 /* LUT based on 1/5th the...*/ | ||
961 | divw r5,r5,r6 /*..loop count used */ | ||
962 | sync | ||
963 | isync | ||
964 | |||
965 | /*--------------------------------------------------------------------+ | ||
966 | | Look-up core speed based on TBC value | ||
967 | +--------------------------------------------------------------------*/ | ||
968 | lis r6,gcs_lookup_table@h /* r6 <- pts at core spd LUT*/ | ||
969 | ori r6,r6,gcs_lookup_table@l | ||
970 | bl gcs_cspd_lookup /* find core speed in LUT */ | ||
971 | |||
972 | mtlr r0 /* set return address */ | ||
973 | blr | ||
974 | function_epilog(initb_get_cspd) | ||
975 | |||
976 | #endif | ||
977 | /*****************************************************************************+ | ||
978 | | XXXX XX XX XXXXXX XXXXXXX XXXXXX XX XX XX XXXX | ||
979 | | XX XXX XX X XX X XX X XX XX XXX XX XXXX XX | ||
980 | | XX XXXX XX XX XX X XX XX XXXX XX XX XX XX | ||
981 | | XX XX XXXX XX XXXX XXXXX XX XXXX XX XX XX | ||
982 | | XX XX XXX XX XX X XX XX XX XXX XXXXXX XX | ||
983 | | XX XX XX XX XX X XX XX XX XX XX XX XX XX | ||
984 | | XXXX XX XX XXXX XXXXXXX XXX XX XX XX XX XX XXXXXXX | ||
985 | +*****************************************************************************/ | ||
986 | /****************************************************************************** | ||
987 | | | ||
988 | | Routine: HSMC_CR_WAIT | ||
989 | | | ||
990 | | Purpose: Wait for the HSMC Control Register (bits 12-16) to be reset | ||
991 | | after an auto-refresh, pre-charge or program mode register | ||
992 | | command execution. | ||
993 | | | ||
994 | | Parameters: R3 = HSMC Control Register ID. | ||
995 | | 0: HSMC0 CR0 | ||
996 | | 1: HSMC0 CR1 | ||
997 | | 2: HSMC1 CR0 | ||
998 | | 3: HSMC1 CR1 | ||
999 | | | ||
1000 | | Returns: R3 = 0: Successful | ||
1001 | | -1: Unsuccessful | ||
1002 | | | ||
1003 | ******************************************************************************/ | ||
1004 | hsmc_cr_wait: | ||
1005 | |||
1006 | li r11,10 /* r11 <- retry counter */ | ||
1007 | mtctr r11 /* set retry counter */ | ||
1008 | mr r11,r3 /* r11 <- HSMC CR reg id */ | ||
1009 | |||
1010 | hsmc_cr_rep: | ||
1011 | bdz hsmc_cr_err /* branch if max retries hit*/ | ||
1012 | |||
1013 | /*--------------------------------------------------------------------+ | ||
1014 | | GET HSMCx_CRx value based on HSMC Control Register ID | ||
1015 | +--------------------------------------------------------------------*/ | ||
1016 | try_hsmc0_cr0: /* CHECK IF ID=HSMC0 CR0 REG*/ | ||
1017 | cmpwi cr0,r11,0x0000 | ||
1018 | bne cr0,try_hsmc0_cr1 | ||
1019 | mfdcr r10,hsmc0_cr0 /* r11 <- HSMC0 CR0 value */ | ||
1020 | b hsmc_cr_read | ||
1021 | |||
1022 | try_hsmc0_cr1: /* CHECK IF ID=HSMC0 CR1 REG*/ | ||
1023 | cmpwi cr0,r11,0x0001 | ||
1024 | bne cr0,try_hsmc1_cr0 | ||
1025 | mfdcr r10,hsmc0_cr1 /* r10 <- HSMC0 CR1 value */ | ||
1026 | b hsmc_cr_read | ||
1027 | |||
1028 | try_hsmc1_cr0: /* CHECK IF ID=HSMC1 CR0 REG*/ | ||
1029 | cmpwi cr0,r11,0x0002 | ||
1030 | bne cr0,try_hsmc1_cr1 | ||
1031 | mfdcr r10,hsmc1_cr0 /* r10 <- HSMC1 CR0 value */ | ||
1032 | b hsmc_cr_read | ||
1033 | |||
1034 | try_hsmc1_cr1: /* CHECK IF ID=HSMC1 CR1 REG*/ | ||
1035 | cmpwi cr0,r11,0x0003 | ||
1036 | bne cr0,hsmc_cr_err | ||
1037 | mfdcr r10,hsmc1_cr1 /* r10 <- HSMC1 CR1 value */ | ||
1038 | |||
1039 | /*--------------------------------------------------------------------+ | ||
1040 | | Check if HSMC CR register was reset after command execution | ||
1041 | +--------------------------------------------------------------------*/ | ||
1042 | hsmc_cr_read: | ||
1043 | lis r12,0x000F /* create "AND" mask */ | ||
1044 | ori r12,r12,0x8000 | ||
1045 | and. r10,r10,r12 /* r10 <- HSMC CR bits 12-16*/ | ||
1046 | bne cr0,hsmc_cr_rep /* wait for bits to reset */ | ||
1047 | li r3,0 /* set return code = success*/ | ||
1048 | b hsmc_cr_done | ||
1049 | |||
1050 | hsmc_cr_err: /* ERROR: SDRAM didn't reset*/ | ||
1051 | li r3,-1 /* set RC=unsuccessful */ | ||
1052 | |||
1053 | hsmc_cr_done: | ||
1054 | blr | ||
1055 | |||
1056 | #if 0 | ||
1057 | /****************************************************************************** | ||
1058 | | | ||
1059 | | Routine: GCS_CSPD_LOOKUP | ||
1060 | | | ||
1061 | | Purpose: Uses the number of 13.5 Mhz clock ticks found after executing | ||
1062 | | the branch instruction time loop to look-up the CPU Core Speed | ||
1063 | | in the Core Speed Look-up Table. | ||
1064 | | | ||
1065 | | Parameters: R3 = Address of Bus Speed | ||
1066 | | R4 = Address of Core Speed | ||
1067 | | R5 = Number of 13.5 Mhz clock ticks found in time loop. | ||
1068 | | R6 = Pointer to Core-Speed Look-Up Table | ||
1069 | | | ||
1070 | | Returns: (R3) = >0: Bus Speed. | ||
1071 | | 0: Bus Speed not found in Look-Up Table. | ||
1072 | | (R4) = >0: Core Speed. | ||
1073 | | 0: Core Speed not found in Look-Up Table. | ||
1074 | | | ||
1075 | | Note: Core Speed = Bus Speed * Mult Factor (1-4x). | ||
1076 | | | ||
1077 | ******************************************************************************/ | ||
1078 | gcs_cspd_lookup: | ||
1079 | |||
1080 | li r9,1 /* r9 <- core speed mult */ | ||
1081 | /*--------------------------------------------------------------------+ | ||
1082 | | Get theoritical number 13.5 Mhz ticks for a given Bus Speed from | ||
1083 | | Look-up Table. Check all mult factors to determine if calculated | ||
1084 | | value matches theoretical value (within a tolerance). | ||
1085 | +--------------------------------------------------------------------*/ | ||
1086 | gcs_cspd_loop: | ||
1087 | lwz r10,0(r6) /* r10 <- no. ticks from LUT*/ | ||
1088 | divw r10,r10,r9 /* r10 <- div mult (1-4x) */ | ||
1089 | subi r11,r10,GCS_CTICK_TOL /* r11 <- no. tks low range */ | ||
1090 | addi r12,r10,GCS_CTICK_TOL /* r12 <- no. tks high range*/ | ||
1091 | |||
1092 | cmpw cr0,r5,r11 /* calc value within range? */ | ||
1093 | blt gcs_cspd_retry /* less than low range */ | ||
1094 | cmpw cr0,r5,r12 | ||
1095 | bgt gcs_cspd_retry /* greater than high range */ | ||
1096 | b gcs_cspd_fnd /* calc value within range */ | ||
1097 | |||
1098 | /*--------------------------------------------------------------------+ | ||
1099 | | SO FAR CORE SPEED NOT FOUND: Check next mult factor | ||
1100 | +--------------------------------------------------------------------*/ | ||
1101 | gcs_cspd_retry: | ||
1102 | addi r9,r9,1 /* bump mult factor (1-4x) */ | ||
1103 | cmpwi cr0,r9,GCS_NMULT | ||
1104 | ble gcs_cspd_loop | ||
1105 | |||
1106 | /*--------------------------------------------------------------------+ | ||
1107 | | SO FAR CORE SPEED NOT FOUND: Point at next Bus Speed in LUT | ||
1108 | +--------------------------------------------------------------------*/ | ||
1109 | li r9,1 /* reset mult factor */ | ||
1110 | addi r6,r6,GCS_TROW_BYTES /* point at next table entry*/ | ||
1111 | lwz r10,0(r6) | ||
1112 | cmpwi cr0,r10,0 /* check for EOT flag */ | ||
1113 | bne gcs_cspd_loop | ||
1114 | |||
1115 | /*--------------------------------------------------------------------+ | ||
1116 | | COMPUTE CORE SPEED AND GET BUS SPEED FROM LOOK-UP TABLE | ||
1117 | +--------------------------------------------------------------------*/ | ||
1118 | gcs_cspd_fnd: | ||
1119 | lwz r5,4(r6) /* r5 <- Bus Speed in LUT */ | ||
1120 | mullw r6,r5,r9 /* r6 <- Core speed */ | ||
1121 | stw r5,0(r3) /* (r3) <- Bus Speed */ | ||
1122 | stw r6,0(r4) /* (r4) <- Core Speed */ | ||
1123 | |||
1124 | blr | ||
1125 | #endif | ||
diff --git a/arch/ppc/boot/simple/rw4/stb.h b/arch/ppc/boot/simple/rw4/stb.h new file mode 100644 index 000000000000..fd98ee0f843e --- /dev/null +++ b/arch/ppc/boot/simple/rw4/stb.h | |||
@@ -0,0 +1,239 @@ | |||
1 | /*----------------------------------------------------------------------------+ | ||
2 | | This source code has been made available to you by IBM on an AS-IS | ||
3 | | basis. Anyone receiving this source is licensed under IBM | ||
4 | | copyrights to use it in any way he or she deems fit, including | ||
5 | | copying it, modifying it, compiling it, and redistributing it either | ||
6 | | with or without modifications. No license under IBM patents or | ||
7 | | patent applications is to be implied by the copyright license. | ||
8 | | | ||
9 | | Any user of this software should understand that IBM cannot provide | ||
10 | | technical support for this software and will not be responsible for | ||
11 | | any consequences resulting from the use of this software. | ||
12 | | | ||
13 | | Any person who transfers this source code or any derivative work | ||
14 | | must include the IBM copyright notice, this paragraph, and the | ||
15 | | preceding two paragraphs in the transferred software. | ||
16 | | | ||
17 | | COPYRIGHT I B M CORPORATION 1999 | ||
18 | | LICENSED MATERIAL - PROGRAM PROPERTY OF I B M | ||
19 | +----------------------------------------------------------------------------*/ | ||
20 | /*----------------------------------------------------------------------------+ | ||
21 | | Author: Maciej P. Tyrlik | ||
22 | | Component: Include file. | ||
23 | | File: stb.h | ||
24 | | Purpose: Common Set-tob-box definitions. | ||
25 | | Changes: | ||
26 | | Date: Comment: | ||
27 | | ----- -------- | ||
28 | | 14-Jan-97 Created for ElPaso pass 1 MPT | ||
29 | | 13-May-97 Added function prototype and global variables MPT | ||
30 | | 08-Dec-98 Added RAW IR task information MPT | ||
31 | | 19-Jan-99 Port to Romeo MPT | ||
32 | | 19-May-00 Changed SDRAM to 32MB contiguous 0x1F000000 - 0x20FFFFFF RLB | ||
33 | +----------------------------------------------------------------------------*/ | ||
34 | |||
35 | #ifndef _stb_h_ | ||
36 | #define _stb_h_ | ||
37 | |||
38 | /*----------------------------------------------------------------------------+ | ||
39 | | Read/write from I/O macros. | ||
40 | +----------------------------------------------------------------------------*/ | ||
41 | #define inbyte(port) (*((unsigned char volatile *)(port))) | ||
42 | #define outbyte(port,data) *(unsigned char volatile *)(port)=\ | ||
43 | (unsigned char)(data) | ||
44 | |||
45 | #define inshort(port) (*((unsigned short volatile *)(port))) | ||
46 | #define outshort(port,data) *(unsigned short volatile *)(port)=\ | ||
47 | (unsigned short)(data) | ||
48 | |||
49 | #define inword(port) (*((unsigned long volatile *)(port))) | ||
50 | #define outword(port,data) *(unsigned long volatile *)(port)=\ | ||
51 | (unsigned long)(data) | ||
52 | |||
53 | /*----------------------------------------------------------------------------+ | ||
54 | | STB interrupts. | ||
55 | +----------------------------------------------------------------------------*/ | ||
56 | #define STB_XP_TP_INT 0 | ||
57 | #define STB_XP_APP_INT 1 | ||
58 | #define STB_AUD_INT 2 | ||
59 | #define STB_VID_INT 3 | ||
60 | #define STB_DMA0_INT 4 | ||
61 | #define STB_DMA1_INT 5 | ||
62 | #define STB_DMA2_INT 6 | ||
63 | #define STB_DMA3_INT 7 | ||
64 | #define STB_SCI_INT 8 | ||
65 | #define STB_I2C1_INT 9 | ||
66 | #define STB_I2C2_INT 10 | ||
67 | #define STB_GPT_PWM0 11 | ||
68 | #define STB_GPT_PWM1 12 | ||
69 | #define STB_SCP_INT 13 | ||
70 | #define STB_SSP_INT 14 | ||
71 | #define STB_GPT_PWM2 15 | ||
72 | #define STB_EXT5_INT 16 | ||
73 | #define STB_EXT6_INT 17 | ||
74 | #define STB_EXT7_INT 18 | ||
75 | #define STB_EXT8_INT 19 | ||
76 | #define STB_SCC_INT 20 | ||
77 | #define STB_SICC_RECV_INT 21 | ||
78 | #define STB_SICC_TRAN_INT 22 | ||
79 | #define STB_PPU_INT 23 | ||
80 | #define STB_DCRX_INT 24 | ||
81 | #define STB_EXT0_INT 25 | ||
82 | #define STB_EXT1_INT 26 | ||
83 | #define STB_EXT2_INT 27 | ||
84 | #define STB_EXT3_INT 28 | ||
85 | #define STB_EXT4_INT 29 | ||
86 | #define STB_REDWOOD_ENET_INT STB_EXT1_INT | ||
87 | |||
88 | /*----------------------------------------------------------------------------+ | ||
89 | | STB tasks, task stack sizes, and task priorities. The actual task priority | ||
90 | | is 1 more than the specified number since priority 0 is reserved (system | ||
91 | | internaly adds 1 to supplied priority number). | ||
92 | +----------------------------------------------------------------------------*/ | ||
93 | #define STB_IDLE_TASK_SS (5* 1024) | ||
94 | #define STB_IDLE_TASK_PRIO 0 | ||
95 | #define STB_LEDTEST_SS (2* 1024) | ||
96 | #define STB_LEDTEST_PRIO 0 | ||
97 | #define STB_CURSOR_TASK_SS (10* 1024) | ||
98 | #define STB_CURSOR_TASK_PRIO 7 | ||
99 | #define STB_MPEG_TASK_SS (10* 1024) | ||
100 | #define STB_MPEG_TASK_PRIO 9 | ||
101 | #define STB_DEMUX_TASK_SS (10* 1024) | ||
102 | #define STB_DEMUX_TASK_PRIO 20 | ||
103 | #define RAW_STB_IR_TASK_SS (10* 1024) | ||
104 | #define RAW_STB_IR_TASK_PRIO 20 | ||
105 | |||
106 | #define STB_SERIAL_ER_TASK_SS (10* 1024) | ||
107 | #define STB_SERIAL_ER_TASK_PRIO 1 | ||
108 | #define STB_CA_TASK_SS (10* 1024) | ||
109 | #define STB_CA_TASK_PRIO 8 | ||
110 | |||
111 | #define INIT_DEFAULT_VIDEO_SS (10* 1024) | ||
112 | #define INIT_DEFAULT_VIDEO_PRIO 8 | ||
113 | #define INIT_DEFAULT_SERVI_SS (10* 1024) | ||
114 | #define INIT_DEFAULT_SERVI_PRIO 8 | ||
115 | #define INIT_DEFAULT_POST_SS (10* 1024) | ||
116 | #define INIT_DEFAULT_POST_PRIO 8 | ||
117 | #define INIT_DEFAULT_INTER_SS (10* 1024) | ||
118 | #define INIT_DEFAULT_INTER_PRIO 8 | ||
119 | #define INIT_DEFAULT_BR_SS (10* 1024) | ||
120 | #define INIT_DEFAULT_BR_PRIO 8 | ||
121 | #define INITIAL_TASK_STACK_SIZE (32* 1024) | ||
122 | |||
123 | #ifdef VESTA | ||
124 | /*----------------------------------------------------------------------------+ | ||
125 | | Vesta Overall Address Map (all addresses are double mapped, bit 0 of the | ||
126 | | address is not decoded. Numbers below are dependent on board configuration. | ||
127 | | FLASH, SDRAM, DRAM numbers can be affected by actual board setup. | ||
128 | | | ||
129 | | FFE0,0000 - FFFF,FFFF FLASH | ||
130 | | F200,0000 - F210,FFFF FPGA logic | ||
131 | | Ethernet = F200,0000 | ||
132 | | LED Display = F200,0100 | ||
133 | | Xilinx #1 Regs = F204,0000 | ||
134 | | Xilinx #2 Regs = F208,0000 | ||
135 | | Spare = F20C,0000 | ||
136 | | IDE CS0 = F210,0000 | ||
137 | | F410,0000 - F410,FFFF IDE CS1 | ||
138 | | C000,0000 - C7FF,FFFF OBP | ||
139 | | C000,0000 - C000,0014 SICC (16550 + infra red) | ||
140 | | C001,0000 - C001,0018 PPU (Parallel Port) | ||
141 | | C002,0000 - C002,001B SC0 (Smart Card 0) | ||
142 | | C003,0000 - C003,000F I2C0 | ||
143 | | C004,0000 - C004,0009 SCC (16550 UART) | ||
144 | | C005,0000 - C005,0124 GPT (Timers) | ||
145 | | C006,0000 - C006,0058 GPIO0 | ||
146 | | C007,0000 - C007,001b SC1 (Smart Card 1) | ||
147 | | C008,0000 - C008,FFFF Unused | ||
148 | | C009,0000 - C009,FFFF Unused | ||
149 | | C00A,0000 - C00A,FFFF Unused | ||
150 | | C00B,0000 - C00B,000F I2C1 | ||
151 | | C00C,0000 - C00C,0006 SCP | ||
152 | | C00D,0000 - C00D,0010 SSP | ||
153 | | A000,0000 - A0FF,FFFF SDRAM1 (16M) | ||
154 | | 0000,0000 - 00FF,FFFF SDRAM0 (16M) | ||
155 | +----------------------------------------------------------------------------*/ | ||
156 | #define STB_FLASH_BASE_ADDRESS 0xFFE00000 | ||
157 | #define STB_FPGA_BASE_ADDRESS 0xF2000000 | ||
158 | #define STB_SICC_BASE_ADDRESS 0xC0000000 | ||
159 | #define STB_PPU_BASE_ADDR 0xC0010000 | ||
160 | #define STB_SC0_BASE_ADDRESS 0xC0020000 | ||
161 | #define STB_I2C1_BASE_ADDRESS 0xC0030000 | ||
162 | #define STB_SCC_BASE_ADDRESS 0xC0040000 | ||
163 | #define STB_TIMERS_BASE_ADDRESS 0xC0050000 | ||
164 | #define STB_GPIO0_BASE_ADDRESS 0xC0060000 | ||
165 | #define STB_SC1_BASE_ADDRESS 0xC0070000 | ||
166 | #define STB_I2C2_BASE_ADDRESS 0xC00B0000 | ||
167 | #define STB_SCP_BASE_ADDRESS 0xC00C0000 | ||
168 | #define STB_SSP_BASE_ADDRESS 0xC00D0000 | ||
169 | /*----------------------------------------------------------------------------+ | ||
170 | |The following are used by the IBM RTOS SW. | ||
171 | |15-May-00 Changed these values to reflect movement of base addresses in | ||
172 | |order to support 32MB of contiguous SDRAM space. | ||
173 | |Points to the cacheable region since these values are used in IBM RTOS | ||
174 | |to establish the vector address. | ||
175 | +----------------------------------------------------------------------------*/ | ||
176 | #define STB_SDRAM1_BASE_ADDRESS 0x20000000 | ||
177 | #define STB_SDRAM1_SIZE 0x01000000 | ||
178 | #define STB_SDRAM0_BASE_ADDRESS 0x1F000000 | ||
179 | #define STB_SDRAM0_SIZE 0x01000000 | ||
180 | |||
181 | #else | ||
182 | /*----------------------------------------------------------------------------+ | ||
183 | | ElPaso Overall Address Map (all addresses are double mapped, bit 0 of the | ||
184 | | address is not decoded. Numbers below are dependent on board configuration. | ||
185 | | FLASH, SDRAM, DRAM numbers can be affected by actual board setup. OPB | ||
186 | | devices are inside the ElPaso chip. | ||
187 | | FFE0,0000 - FFFF,FFFF FLASH | ||
188 | | F144,0000 - F104,FFFF FPGA logic | ||
189 | | F140,0000 - F100,0000 ethernet (through FPGA logic) | ||
190 | | C000,0000 - C7FF,FFFF OBP | ||
191 | | C000,0000 - C000,0014 SICC (16550+ infra red) | ||
192 | | C001,0000 - C001,0016 PPU (parallel port) | ||
193 | | C002,0000 - C002,001B SC (smart card) | ||
194 | | C003,0000 - C003,000F I2C 1 | ||
195 | | C004,0000 - C004,0009 SCC (16550 UART) | ||
196 | | C005,0000 - C005,0124 Timers | ||
197 | | C006,0000 - C006,0058 GPIO0 | ||
198 | | C007,0000 - C007,0058 GPIO1 | ||
199 | | C008,0000 - C008,0058 GPIO2 | ||
200 | | C009,0000 - C009,0058 GPIO3 | ||
201 | | C00A,0000 - C00A,0058 GPIO4 | ||
202 | | C00B,0000 - C00B,000F I2C 2 | ||
203 | | C00C,0000 - C00C,0006 SCP | ||
204 | | C00D,0000 - C00D,0006 SSP | ||
205 | | A000,0000 - A0FF,FFFF SDRAM 16M | ||
206 | | 0000,0000 - 00FF,FFFF DRAM 16M | ||
207 | +----------------------------------------------------------------------------*/ | ||
208 | #define STB_FLASH_BASE_ADDRESS 0xFFE00000 | ||
209 | #define STB_FPGA_BASE_ADDRESS 0xF1440000 | ||
210 | #define STB_ENET_BASE_ADDRESS 0xF1400000 | ||
211 | #define STB_SICC_BASE_ADDRESS 0xC0000000 | ||
212 | #define STB_PPU_BASE_ADDR 0xC0010000 | ||
213 | #define STB_SC_BASE_ADDRESS 0xC0020000 | ||
214 | #define STB_I2C1_BASE_ADDRESS 0xC0030000 | ||
215 | #define STB_SCC_BASE_ADDRESS 0xC0040000 | ||
216 | #define STB_TIMERS_BASE_ADDRESS 0xC0050000 | ||
217 | #define STB_GPIO0_BASE_ADDRESS 0xC0060000 | ||
218 | #define STB_GPIO1_BASE_ADDRESS 0xC0070000 | ||
219 | #define STB_GPIO2_BASE_ADDRESS 0xC0080000 | ||
220 | #define STB_GPIO3_BASE_ADDRESS 0xC0090000 | ||
221 | #define STB_GPIO4_BASE_ADDRESS 0xC00A0000 | ||
222 | #define STB_I2C2_BASE_ADDRESS 0xC00B0000 | ||
223 | #define STB_SCP_BASE_ADDRESS 0xC00C0000 | ||
224 | #define STB_SSP_BASE_ADDRESS 0xC00D0000 | ||
225 | #define STB_SDRAM_BASE_ADDRESS 0xA0000000 | ||
226 | #endif | ||
227 | |||
228 | /*----------------------------------------------------------------------------+ | ||
229 | | Other common defines. | ||
230 | +----------------------------------------------------------------------------*/ | ||
231 | #ifndef TRUE | ||
232 | #define TRUE 1 | ||
233 | #endif | ||
234 | |||
235 | #ifndef FALSE | ||
236 | #define FALSE 0 | ||
237 | #endif | ||
238 | |||
239 | #endif /* _stb_h_ */ | ||
diff --git a/arch/ppc/boot/utils/addRamDisk.c b/arch/ppc/boot/utils/addRamDisk.c new file mode 100644 index 000000000000..93400dfcce7f --- /dev/null +++ b/arch/ppc/boot/utils/addRamDisk.c | |||
@@ -0,0 +1,203 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <netinet/in.h> | ||
4 | #include <unistd.h> | ||
5 | #include <sys/types.h> | ||
6 | #include <sys/stat.h> | ||
7 | #include <string.h> | ||
8 | |||
9 | #define ElfHeaderSize (64 * 1024) | ||
10 | #define ElfPages (ElfHeaderSize / 4096) | ||
11 | #define KERNELBASE (0xc0000000) | ||
12 | |||
13 | void get4k(FILE *file, char *buf ) | ||
14 | { | ||
15 | unsigned j; | ||
16 | unsigned num = fread(buf, 1, 4096, file); | ||
17 | for ( j=num; j<4096; ++j ) | ||
18 | buf[j] = 0; | ||
19 | } | ||
20 | |||
21 | void put4k(FILE *file, char *buf ) | ||
22 | { | ||
23 | fwrite(buf, 1, 4096, file); | ||
24 | } | ||
25 | |||
26 | void death(const char *msg, FILE *fdesc, const char *fname) | ||
27 | { | ||
28 | printf(msg); | ||
29 | fclose(fdesc); | ||
30 | unlink(fname); | ||
31 | exit(1); | ||
32 | } | ||
33 | |||
34 | int main(int argc, char **argv) | ||
35 | { | ||
36 | char inbuf[4096]; | ||
37 | FILE *ramDisk = NULL; | ||
38 | FILE *inputVmlinux = NULL; | ||
39 | FILE *outputVmlinux = NULL; | ||
40 | unsigned i = 0; | ||
41 | u_int32_t ramFileLen = 0; | ||
42 | u_int32_t ramLen = 0; | ||
43 | u_int32_t roundR = 0; | ||
44 | u_int32_t kernelLen = 0; | ||
45 | u_int32_t actualKernelLen = 0; | ||
46 | u_int32_t round = 0; | ||
47 | u_int32_t roundedKernelLen = 0; | ||
48 | u_int32_t ramStartOffs = 0; | ||
49 | u_int32_t ramPages = 0; | ||
50 | u_int32_t roundedKernelPages = 0; | ||
51 | u_int32_t hvReleaseData = 0; | ||
52 | u_int32_t eyeCatcher = 0xc8a5d9c4; | ||
53 | u_int32_t naca = 0; | ||
54 | u_int32_t xRamDisk = 0; | ||
55 | u_int32_t xRamDiskSize = 0; | ||
56 | if ( argc < 2 ) { | ||
57 | printf("Name of RAM disk file missing.\n"); | ||
58 | exit(1); | ||
59 | } | ||
60 | |||
61 | if ( argc < 3 ) { | ||
62 | printf("Name of vmlinux file missing.\n"); | ||
63 | exit(1); | ||
64 | } | ||
65 | |||
66 | if ( argc < 4 ) { | ||
67 | printf("Name of vmlinux output file missing.\n"); | ||
68 | exit(1); | ||
69 | } | ||
70 | |||
71 | ramDisk = fopen(argv[1], "r"); | ||
72 | if ( ! ramDisk ) { | ||
73 | printf("RAM disk file \"%s\" failed to open.\n", argv[1]); | ||
74 | exit(1); | ||
75 | } | ||
76 | inputVmlinux = fopen(argv[2], "r"); | ||
77 | if ( ! inputVmlinux ) { | ||
78 | printf("vmlinux file \"%s\" failed to open.\n", argv[2]); | ||
79 | exit(1); | ||
80 | } | ||
81 | outputVmlinux = fopen(argv[3], "w+"); | ||
82 | if ( ! outputVmlinux ) { | ||
83 | printf("output vmlinux file \"%s\" failed to open.\n", argv[3]); | ||
84 | exit(1); | ||
85 | } | ||
86 | fseek(ramDisk, 0, SEEK_END); | ||
87 | ramFileLen = ftell(ramDisk); | ||
88 | fseek(ramDisk, 0, SEEK_SET); | ||
89 | printf("%s file size = %d\n", argv[1], ramFileLen); | ||
90 | |||
91 | ramLen = ramFileLen; | ||
92 | |||
93 | roundR = 4096 - (ramLen % 4096); | ||
94 | if ( roundR ) { | ||
95 | printf("Rounding RAM disk file up to a multiple of 4096, adding %d\n", roundR); | ||
96 | ramLen += roundR; | ||
97 | } | ||
98 | |||
99 | printf("Rounded RAM disk size is %d\n", ramLen); | ||
100 | fseek(inputVmlinux, 0, SEEK_END); | ||
101 | kernelLen = ftell(inputVmlinux); | ||
102 | fseek(inputVmlinux, 0, SEEK_SET); | ||
103 | printf("kernel file size = %d\n", kernelLen); | ||
104 | if ( kernelLen == 0 ) { | ||
105 | printf("You must have a linux kernel specified as argv[2]\n"); | ||
106 | exit(1); | ||
107 | } | ||
108 | |||
109 | actualKernelLen = kernelLen - ElfHeaderSize; | ||
110 | |||
111 | printf("actual kernel length (minus ELF header) = %d\n", actualKernelLen); | ||
112 | |||
113 | round = actualKernelLen % 4096; | ||
114 | roundedKernelLen = actualKernelLen; | ||
115 | if ( round ) | ||
116 | roundedKernelLen += (4096 - round); | ||
117 | |||
118 | printf("actual kernel length rounded up to a 4k multiple = %d\n", roundedKernelLen); | ||
119 | |||
120 | ramStartOffs = roundedKernelLen; | ||
121 | ramPages = ramLen / 4096; | ||
122 | |||
123 | printf("RAM disk pages to copy = %d\n", ramPages); | ||
124 | |||
125 | // Copy 64K ELF header | ||
126 | for (i=0; i<(ElfPages); ++i) { | ||
127 | get4k( inputVmlinux, inbuf ); | ||
128 | put4k( outputVmlinux, inbuf ); | ||
129 | } | ||
130 | |||
131 | roundedKernelPages = roundedKernelLen / 4096; | ||
132 | |||
133 | fseek(inputVmlinux, ElfHeaderSize, SEEK_SET); | ||
134 | |||
135 | for ( i=0; i<roundedKernelPages; ++i ) { | ||
136 | get4k( inputVmlinux, inbuf ); | ||
137 | put4k( outputVmlinux, inbuf ); | ||
138 | } | ||
139 | |||
140 | for ( i=0; i<ramPages; ++i ) { | ||
141 | get4k( ramDisk, inbuf ); | ||
142 | put4k( outputVmlinux, inbuf ); | ||
143 | } | ||
144 | |||
145 | /* Close the input files */ | ||
146 | fclose(ramDisk); | ||
147 | fclose(inputVmlinux); | ||
148 | /* And flush the written output file */ | ||
149 | fflush(outputVmlinux); | ||
150 | |||
151 | /* fseek to the hvReleaseData pointer */ | ||
152 | fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET); | ||
153 | if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) { | ||
154 | death("Could not read hvReleaseData pointer\n", outputVmlinux, argv[3]); | ||
155 | } | ||
156 | hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */ | ||
157 | printf("hvReleaseData is at %08x\n", hvReleaseData); | ||
158 | |||
159 | /* fseek to the hvReleaseData */ | ||
160 | fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET); | ||
161 | if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) { | ||
162 | death("Could not read hvReleaseData\n", outputVmlinux, argv[3]); | ||
163 | } | ||
164 | /* Check hvReleaseData sanity */ | ||
165 | if (memcmp(inbuf, &eyeCatcher, 4) != 0) { | ||
166 | death("hvReleaseData is invalid\n", outputVmlinux, argv[3]); | ||
167 | } | ||
168 | /* Get the naca pointer */ | ||
169 | naca = ntohl(*((u_int32_t *) &inbuf[0x0c])) - KERNELBASE; | ||
170 | printf("naca is at %08x\n", naca); | ||
171 | |||
172 | /* fseek to the naca */ | ||
173 | fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); | ||
174 | if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) { | ||
175 | death("Could not read naca\n", outputVmlinux, argv[3]); | ||
176 | } | ||
177 | xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c])); | ||
178 | xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14])); | ||
179 | /* Make sure a RAM disk isn't already present */ | ||
180 | if ((xRamDisk != 0) || (xRamDiskSize != 0)) { | ||
181 | death("RAM disk is already attached to this kernel\n", outputVmlinux, argv[3]); | ||
182 | } | ||
183 | /* Fill in the values */ | ||
184 | *((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs); | ||
185 | *((u_int32_t *) &inbuf[0x14]) = htonl(ramPages); | ||
186 | |||
187 | /* Write out the new naca */ | ||
188 | fflush(outputVmlinux); | ||
189 | fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); | ||
190 | if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) { | ||
191 | death("Could not write naca\n", outputVmlinux, argv[3]); | ||
192 | } | ||
193 | printf("RAM Disk of 0x%x pages size is attached to the kernel at offset 0x%08x\n", | ||
194 | ramPages, ramStartOffs); | ||
195 | |||
196 | /* Done */ | ||
197 | fclose(outputVmlinux); | ||
198 | /* Set permission to executable */ | ||
199 | chmod(argv[3], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
diff --git a/arch/ppc/boot/utils/addSystemMap.c b/arch/ppc/boot/utils/addSystemMap.c new file mode 100644 index 000000000000..4654f891b274 --- /dev/null +++ b/arch/ppc/boot/utils/addSystemMap.c | |||
@@ -0,0 +1,186 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <byteswap.h> | ||
4 | #include <sys/types.h> | ||
5 | #include <sys/stat.h> | ||
6 | |||
7 | void xlate( char * inb, char * trb, unsigned len ) | ||
8 | { | ||
9 | unsigned i; | ||
10 | for ( i=0; i<len; ++i ) { | ||
11 | char c = *inb++; | ||
12 | char c1 = c >> 4; | ||
13 | char c2 = c & 0xf; | ||
14 | if ( c1 > 9 ) | ||
15 | c1 = c1 + 'A' - 10; | ||
16 | else | ||
17 | c1 = c1 + '0'; | ||
18 | if ( c2 > 9 ) | ||
19 | c2 = c2 + 'A' - 10; | ||
20 | else | ||
21 | c2 = c2 + '0'; | ||
22 | *trb++ = c1; | ||
23 | *trb++ = c2; | ||
24 | } | ||
25 | *trb = 0; | ||
26 | } | ||
27 | |||
28 | #define ElfHeaderSize (64 * 1024) | ||
29 | #define ElfPages (ElfHeaderSize / 4096) | ||
30 | #define KERNELBASE (0xc0000000) | ||
31 | |||
32 | void get4k( /*istream *inf*/FILE *file, char *buf ) | ||
33 | { | ||
34 | unsigned j; | ||
35 | unsigned num = fread(buf, 1, 4096, file); | ||
36 | for ( j=num; j<4096; ++j ) | ||
37 | buf[j] = 0; | ||
38 | } | ||
39 | |||
40 | void put4k( /*ostream *outf*/FILE *file, char *buf ) | ||
41 | { | ||
42 | fwrite(buf, 1, 4096, file); | ||
43 | } | ||
44 | |||
45 | int main(int argc, char **argv) | ||
46 | { | ||
47 | char inbuf[4096]; | ||
48 | FILE *ramDisk = NULL; | ||
49 | FILE *inputVmlinux = NULL; | ||
50 | FILE *outputVmlinux = NULL; | ||
51 | unsigned i = 0; | ||
52 | unsigned long ramFileLen = 0; | ||
53 | unsigned long ramLen = 0; | ||
54 | unsigned long roundR = 0; | ||
55 | unsigned long kernelLen = 0; | ||
56 | unsigned long actualKernelLen = 0; | ||
57 | unsigned long round = 0; | ||
58 | unsigned long roundedKernelLen = 0; | ||
59 | unsigned long ramStartOffs = 0; | ||
60 | unsigned long ramPages = 0; | ||
61 | unsigned long roundedKernelPages = 0; | ||
62 | if ( argc < 2 ) { | ||
63 | printf("Name of System Map file missing.\n"); | ||
64 | exit(1); | ||
65 | } | ||
66 | |||
67 | if ( argc < 3 ) { | ||
68 | printf("Name of vmlinux file missing.\n"); | ||
69 | exit(1); | ||
70 | } | ||
71 | |||
72 | if ( argc < 4 ) { | ||
73 | printf("Name of vmlinux output file missing.\n"); | ||
74 | exit(1); | ||
75 | } | ||
76 | |||
77 | ramDisk = fopen(argv[1], "r"); | ||
78 | if ( ! ramDisk ) { | ||
79 | printf("System Map file \"%s\" failed to open.\n", argv[1]); | ||
80 | exit(1); | ||
81 | } | ||
82 | inputVmlinux = fopen(argv[2], "r"); | ||
83 | if ( ! inputVmlinux ) { | ||
84 | printf("vmlinux file \"%s\" failed to open.\n", argv[2]); | ||
85 | exit(1); | ||
86 | } | ||
87 | outputVmlinux = fopen(argv[3], "w"); | ||
88 | if ( ! outputVmlinux ) { | ||
89 | printf("output vmlinux file \"%s\" failed to open.\n", argv[3]); | ||
90 | exit(1); | ||
91 | } | ||
92 | fseek(ramDisk, 0, SEEK_END); | ||
93 | ramFileLen = ftell(ramDisk); | ||
94 | fseek(ramDisk, 0, SEEK_SET); | ||
95 | printf("%s file size = %ld\n", argv[1], ramFileLen); | ||
96 | |||
97 | ramLen = ramFileLen; | ||
98 | |||
99 | roundR = 4096 - (ramLen % 4096); | ||
100 | if ( roundR ) { | ||
101 | printf("Rounding System Map file up to a multiple of 4096, adding %ld\n", roundR); | ||
102 | ramLen += roundR; | ||
103 | } | ||
104 | |||
105 | printf("Rounded System Map size is %ld\n", ramLen); | ||
106 | fseek(inputVmlinux, 0, SEEK_END); | ||
107 | kernelLen = ftell(inputVmlinux); | ||
108 | fseek(inputVmlinux, 0, SEEK_SET); | ||
109 | printf("kernel file size = %ld\n", kernelLen); | ||
110 | if ( kernelLen == 0 ) { | ||
111 | printf("You must have a linux kernel specified as argv[2]\n"); | ||
112 | exit(1); | ||
113 | } | ||
114 | |||
115 | actualKernelLen = kernelLen - ElfHeaderSize; | ||
116 | |||
117 | printf("actual kernel length (minus ELF header) = %ld\n", actualKernelLen); | ||
118 | |||
119 | round = actualKernelLen % 4096; | ||
120 | roundedKernelLen = actualKernelLen; | ||
121 | if ( round ) | ||
122 | roundedKernelLen += (4096 - round); | ||
123 | |||
124 | printf("actual kernel length rounded up to a 4k multiple = %ld\n", roundedKernelLen); | ||
125 | |||
126 | ramStartOffs = roundedKernelLen; | ||
127 | ramPages = ramLen / 4096; | ||
128 | |||
129 | printf("System map pages to copy = %ld\n", ramPages); | ||
130 | |||
131 | // Copy 64K ELF header | ||
132 | for (i=0; i<(ElfPages); ++i) { | ||
133 | get4k( inputVmlinux, inbuf ); | ||
134 | put4k( outputVmlinux, inbuf ); | ||
135 | } | ||
136 | |||
137 | |||
138 | |||
139 | roundedKernelPages = roundedKernelLen / 4096; | ||
140 | |||
141 | fseek(inputVmlinux, ElfHeaderSize, SEEK_SET); | ||
142 | |||
143 | { | ||
144 | for ( i=0; i<roundedKernelPages; ++i ) { | ||
145 | get4k( inputVmlinux, inbuf ); | ||
146 | if ( i == 0 ) { | ||
147 | unsigned long * p; | ||
148 | printf("Storing embedded_sysmap_start at 0x3c\n"); | ||
149 | p = (unsigned long *)(inbuf + 0x3c); | ||
150 | |||
151 | #if (BYTE_ORDER == __BIG_ENDIAN) | ||
152 | *p = ramStartOffs; | ||
153 | #else | ||
154 | *p = bswap_32(ramStartOffs); | ||
155 | #endif | ||
156 | |||
157 | printf("Storing embedded_sysmap_end at 0x44\n"); | ||
158 | p = (unsigned long *)(inbuf + 0x44); | ||
159 | #if (BYTE_ORDER == __BIG_ENDIAN) | ||
160 | *p = ramStartOffs + ramFileLen; | ||
161 | #else | ||
162 | *p = bswap_32(ramStartOffs + ramFileLen); | ||
163 | #endif | ||
164 | } | ||
165 | put4k( outputVmlinux, inbuf ); | ||
166 | } | ||
167 | } | ||
168 | |||
169 | { | ||
170 | for ( i=0; i<ramPages; ++i ) { | ||
171 | get4k( ramDisk, inbuf ); | ||
172 | put4k( outputVmlinux, inbuf ); | ||
173 | } | ||
174 | } | ||
175 | |||
176 | |||
177 | fclose(ramDisk); | ||
178 | fclose(inputVmlinux); | ||
179 | fclose(outputVmlinux); | ||
180 | /* Set permission to executable */ | ||
181 | chmod(argv[3], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); | ||
182 | |||
183 | return 0; | ||
184 | |||
185 | } | ||
186 | |||
diff --git a/arch/ppc/boot/utils/addnote.c b/arch/ppc/boot/utils/addnote.c new file mode 100644 index 000000000000..6c52b18f2d04 --- /dev/null +++ b/arch/ppc/boot/utils/addnote.c | |||
@@ -0,0 +1,175 @@ | |||
1 | /* | ||
2 | * Program to hack in a PT_NOTE program header entry in an ELF file. | ||
3 | * This is needed for OF on RS/6000s to load an image correctly. | ||
4 | * Note that OF needs a program header entry for the note, not an | ||
5 | * ELF section. | ||
6 | * | ||
7 | * Copyright 2000 Paul Mackerras. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | * | ||
14 | * Usage: addnote zImage | ||
15 | */ | ||
16 | #include <stdio.h> | ||
17 | #include <stdlib.h> | ||
18 | #include <fcntl.h> | ||
19 | #include <unistd.h> | ||
20 | #include <string.h> | ||
21 | |||
22 | char arch[] = "PowerPC"; | ||
23 | |||
24 | #define N_DESCR 6 | ||
25 | unsigned int descr[N_DESCR] = { | ||
26 | #if 1 | ||
27 | /* values for IBM RS/6000 machines */ | ||
28 | 0xffffffff, /* real-mode = true */ | ||
29 | 0x00c00000, /* real-base, i.e. where we expect OF to be */ | ||
30 | 0xffffffff, /* real-size */ | ||
31 | 0xffffffff, /* virt-base */ | ||
32 | 0xffffffff, /* virt-size */ | ||
33 | 0x4000, /* load-base */ | ||
34 | #else | ||
35 | /* values for longtrail CHRP */ | ||
36 | 0, /* real-mode = false */ | ||
37 | 0xffffffff, /* real-base */ | ||
38 | 0xffffffff, /* real-size */ | ||
39 | 0xffffffff, /* virt-base */ | ||
40 | 0xffffffff, /* virt-size */ | ||
41 | 0x00600000, /* load-base */ | ||
42 | #endif | ||
43 | }; | ||
44 | |||
45 | unsigned char buf[512]; | ||
46 | |||
47 | #define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) | ||
48 | #define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2)) | ||
49 | |||
50 | #define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \ | ||
51 | buf[(off) + 1] = (v) & 0xff) | ||
52 | #define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \ | ||
53 | PUT_16BE((off) + 2, (v))) | ||
54 | |||
55 | /* Structure of an ELF file */ | ||
56 | #define E_IDENT 0 /* ELF header */ | ||
57 | #define E_PHOFF 28 | ||
58 | #define E_PHENTSIZE 42 | ||
59 | #define E_PHNUM 44 | ||
60 | #define E_HSIZE 52 /* size of ELF header */ | ||
61 | |||
62 | #define EI_MAGIC 0 /* offsets in E_IDENT area */ | ||
63 | #define EI_CLASS 4 | ||
64 | #define EI_DATA 5 | ||
65 | |||
66 | #define PH_TYPE 0 /* ELF program header */ | ||
67 | #define PH_OFFSET 4 | ||
68 | #define PH_FILESZ 16 | ||
69 | #define PH_HSIZE 32 /* size of program header */ | ||
70 | |||
71 | #define PT_NOTE 4 /* Program header type = note */ | ||
72 | |||
73 | #define ELFCLASS32 1 | ||
74 | #define ELFDATA2MSB 2 | ||
75 | |||
76 | unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' }; | ||
77 | |||
78 | int main(int ac, char **av) | ||
79 | { | ||
80 | int fd, n, i; | ||
81 | int ph, ps, np; | ||
82 | int nnote, ns; | ||
83 | |||
84 | if (ac != 2) { | ||
85 | fprintf(stderr, "Usage: %s elf-file\n", av[0]); | ||
86 | exit(1); | ||
87 | } | ||
88 | fd = open(av[1], O_RDWR); | ||
89 | if (fd < 0) { | ||
90 | perror(av[1]); | ||
91 | exit(1); | ||
92 | } | ||
93 | |||
94 | nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4; | ||
95 | |||
96 | n = read(fd, buf, sizeof(buf)); | ||
97 | if (n < 0) { | ||
98 | perror("read"); | ||
99 | exit(1); | ||
100 | } | ||
101 | |||
102 | if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0) | ||
103 | goto notelf; | ||
104 | |||
105 | if (buf[E_IDENT+EI_CLASS] != ELFCLASS32 | ||
106 | || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) { | ||
107 | fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n", | ||
108 | av[1]); | ||
109 | exit(1); | ||
110 | } | ||
111 | |||
112 | ph = GET_32BE(E_PHOFF); | ||
113 | ps = GET_16BE(E_PHENTSIZE); | ||
114 | np = GET_16BE(E_PHNUM); | ||
115 | if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) | ||
116 | goto notelf; | ||
117 | if (ph + (np + 1) * ps + nnote > n) | ||
118 | goto nospace; | ||
119 | |||
120 | for (i = 0; i < np; ++i) { | ||
121 | if (GET_32BE(ph + PH_TYPE) == PT_NOTE) { | ||
122 | fprintf(stderr, "%s already has a note entry\n", | ||
123 | av[1]); | ||
124 | exit(0); | ||
125 | } | ||
126 | ph += ps; | ||
127 | } | ||
128 | |||
129 | /* XXX check that the area we want to use is all zeroes */ | ||
130 | for (i = 0; i < ps + nnote; ++i) | ||
131 | if (buf[ph + i] != 0) | ||
132 | goto nospace; | ||
133 | |||
134 | /* fill in the program header entry */ | ||
135 | ns = ph + ps; | ||
136 | PUT_32BE(ph + PH_TYPE, PT_NOTE); | ||
137 | PUT_32BE(ph + PH_OFFSET, ns); | ||
138 | PUT_32BE(ph + PH_FILESZ, nnote); | ||
139 | |||
140 | /* fill in the note area we point to */ | ||
141 | /* XXX we should probably make this a proper section */ | ||
142 | PUT_32BE(ns, strlen(arch) + 1); | ||
143 | PUT_32BE(ns + 4, N_DESCR * 4); | ||
144 | PUT_32BE(ns + 8, 0x1275); | ||
145 | strcpy(&buf[ns + 12], arch); | ||
146 | ns += 12 + strlen(arch) + 1; | ||
147 | for (i = 0; i < N_DESCR; ++i) | ||
148 | PUT_32BE(ns + i * 4, descr[i]); | ||
149 | |||
150 | /* Update the number of program headers */ | ||
151 | PUT_16BE(E_PHNUM, np + 1); | ||
152 | |||
153 | /* write back */ | ||
154 | lseek(fd, (long) 0, SEEK_SET); | ||
155 | i = write(fd, buf, n); | ||
156 | if (i < 0) { | ||
157 | perror("write"); | ||
158 | exit(1); | ||
159 | } | ||
160 | if (i < n) { | ||
161 | fprintf(stderr, "%s: write truncated\n", av[1]); | ||
162 | exit(1); | ||
163 | } | ||
164 | |||
165 | exit(0); | ||
166 | |||
167 | notelf: | ||
168 | fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]); | ||
169 | exit(1); | ||
170 | |||
171 | nospace: | ||
172 | fprintf(stderr, "sorry, I can't find space in %s to put the note\n", | ||
173 | av[0]); | ||
174 | exit(1); | ||
175 | } | ||
diff --git a/arch/ppc/boot/utils/elf.pl b/arch/ppc/boot/utils/elf.pl new file mode 100644 index 000000000000..d3e9d9d5b84e --- /dev/null +++ b/arch/ppc/boot/utils/elf.pl | |||
@@ -0,0 +1,33 @@ | |||
1 | # | ||
2 | # ELF header field numbers | ||
3 | # | ||
4 | |||
5 | $e_ident = 0; # Identification bytes / magic number | ||
6 | $e_type = 1; # ELF file type | ||
7 | $e_machine = 2; # Target machine type | ||
8 | $e_version = 3; # File version | ||
9 | $e_entry = 4; # Start address | ||
10 | $e_phoff = 5; # Program header file offset | ||
11 | $e_shoff = 6; # Section header file offset | ||
12 | $e_flags = 7; # File flags | ||
13 | $e_ehsize = 8; # Size of ELF header | ||
14 | $e_phentsize = 9; # Size of program header | ||
15 | $e_phnum = 10; # Number of program header entries | ||
16 | $e_shentsize = 11; # Size of section header | ||
17 | $e_shnum = 12; # Number of section header entries | ||
18 | $e_shstrndx = 13; # Section header table string index | ||
19 | |||
20 | # | ||
21 | # Section header field numbers | ||
22 | # | ||
23 | |||
24 | $sh_name = 0; # Section name | ||
25 | $sh_type = 1; # Section header type | ||
26 | $sh_flags = 2; # Section header flags | ||
27 | $sh_addr = 3; # Virtual address | ||
28 | $sh_offset = 4; # File offset | ||
29 | $sh_size = 5; # Section size | ||
30 | $sh_link = 6; # Miscellaneous info | ||
31 | $sh_info = 7; # More miscellaneous info | ||
32 | $sh_addralign = 8; # Memory alignment | ||
33 | $sh_entsize = 9; # Entry size if this is a table | ||
diff --git a/arch/ppc/boot/utils/hack-coff.c b/arch/ppc/boot/utils/hack-coff.c new file mode 100644 index 000000000000..5e5a6573a1ef --- /dev/null +++ b/arch/ppc/boot/utils/hack-coff.c | |||
@@ -0,0 +1,84 @@ | |||
1 | /* | ||
2 | * hack-coff.c - hack the header of an xcoff file to fill in | ||
3 | * a few fields needed by the Open Firmware xcoff loader on | ||
4 | * Power Macs but not initialized by objcopy. | ||
5 | * | ||
6 | * Copyright (C) Paul Mackerras 1997. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the License, or (at your option) any later version. | ||
12 | */ | ||
13 | #include <stdio.h> | ||
14 | #include <stdlib.h> | ||
15 | #include <unistd.h> | ||
16 | #include <fcntl.h> | ||
17 | #include <string.h> | ||
18 | #include "rs6000.h" | ||
19 | |||
20 | #define AOUT_MAGIC 0x010b | ||
21 | |||
22 | #define get_16be(x) ((((unsigned char *)(x))[0] << 8) \ | ||
23 | + ((unsigned char *)(x))[1]) | ||
24 | #define put_16be(x, v) (((unsigned char *)(x))[0] = (v) >> 8, \ | ||
25 | ((unsigned char *)(x))[1] = (v) & 0xff) | ||
26 | #define get_32be(x) ((((unsigned char *)(x))[0] << 24) \ | ||
27 | + (((unsigned char *)(x))[1] << 16) \ | ||
28 | + (((unsigned char *)(x))[2] << 8) \ | ||
29 | + ((unsigned char *)(x))[3]) | ||
30 | |||
31 | int | ||
32 | main(int ac, char **av) | ||
33 | { | ||
34 | int fd; | ||
35 | int i, nsect; | ||
36 | int aoutsz; | ||
37 | struct external_filehdr fhdr; | ||
38 | AOUTHDR aout; | ||
39 | struct external_scnhdr shdr; | ||
40 | |||
41 | if (ac != 2) { | ||
42 | fprintf(stderr, "Usage: hack-coff coff-file\n"); | ||
43 | exit(1); | ||
44 | } | ||
45 | if ((fd = open(av[1], 2)) == -1) { | ||
46 | perror(av[2]); | ||
47 | exit(1); | ||
48 | } | ||
49 | if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr)) | ||
50 | goto readerr; | ||
51 | i = get_16be(fhdr.f_magic); | ||
52 | if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) { | ||
53 | fprintf(stderr, "%s: not an xcoff file\n", av[1]); | ||
54 | exit(1); | ||
55 | } | ||
56 | aoutsz = get_16be(fhdr.f_opthdr); | ||
57 | if (read(fd, &aout, aoutsz) != aoutsz) | ||
58 | goto readerr; | ||
59 | nsect = get_16be(fhdr.f_nscns); | ||
60 | for (i = 0; i < nsect; ++i) { | ||
61 | if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr)) | ||
62 | goto readerr; | ||
63 | if (strcmp(shdr.s_name, ".text") == 0) { | ||
64 | put_16be(aout.o_snentry, i+1); | ||
65 | put_16be(aout.o_sntext, i+1); | ||
66 | } else if (strcmp(shdr.s_name, ".data") == 0) { | ||
67 | put_16be(aout.o_sndata, i+1); | ||
68 | } else if (strcmp(shdr.s_name, ".bss") == 0) { | ||
69 | put_16be(aout.o_snbss, i+1); | ||
70 | } | ||
71 | } | ||
72 | put_16be(aout.magic, AOUT_MAGIC); | ||
73 | if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1 | ||
74 | || write(fd, &aout, aoutsz) != aoutsz) { | ||
75 | fprintf(stderr, "%s: write error\n", av[1]); | ||
76 | exit(1); | ||
77 | } | ||
78 | close(fd); | ||
79 | exit(0); | ||
80 | |||
81 | readerr: | ||
82 | fprintf(stderr, "%s: read error or file too short\n", av[1]); | ||
83 | exit(1); | ||
84 | } | ||
diff --git a/arch/ppc/boot/utils/mkbugboot.c b/arch/ppc/boot/utils/mkbugboot.c new file mode 100644 index 000000000000..886122283f39 --- /dev/null +++ b/arch/ppc/boot/utils/mkbugboot.c | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/utils/mkbugboot.c | ||
3 | * | ||
4 | * Makes a Motorola PPCBUG ROM bootable image which can be flashed | ||
5 | * into one of the FLASH banks on a Motorola PowerPlus board. | ||
6 | * | ||
7 | * Author: Matt Porter <mporter@mvista.com> | ||
8 | * | ||
9 | * 2001 (c) MontaVista, Software, Inc. This file is licensed under | ||
10 | * the terms of the GNU General Public License version 2. This program | ||
11 | * is licensed "as is" without any warranty of any kind, whether express | ||
12 | * or implied. | ||
13 | */ | ||
14 | |||
15 | #define ELF_HEADER_SIZE 65536 | ||
16 | |||
17 | #include <unistd.h> | ||
18 | #include <sys/stat.h> | ||
19 | #include <string.h> | ||
20 | #include <stdio.h> | ||
21 | #include <stdlib.h> | ||
22 | #include <errno.h> | ||
23 | #include <fcntl.h> | ||
24 | #ifdef __sun__ | ||
25 | #include <inttypes.h> | ||
26 | #else | ||
27 | #include <stdint.h> | ||
28 | #endif | ||
29 | |||
30 | #ifdef __i386__ | ||
31 | #define cpu_to_be32(x) le32_to_cpu(x) | ||
32 | #define cpu_to_be16(x) le16_to_cpu(x) | ||
33 | #else | ||
34 | #define cpu_to_be32(x) (x) | ||
35 | #define cpu_to_be16(x) (x) | ||
36 | #endif | ||
37 | |||
38 | #define cpu_to_le32(x) le32_to_cpu((x)) | ||
39 | unsigned long le32_to_cpu(unsigned long x) | ||
40 | { | ||
41 | return (((x & 0x000000ffU) << 24) | | ||
42 | ((x & 0x0000ff00U) << 8) | | ||
43 | ((x & 0x00ff0000U) >> 8) | | ||
44 | ((x & 0xff000000U) >> 24)); | ||
45 | } | ||
46 | |||
47 | #define cpu_to_le16(x) le16_to_cpu((x)) | ||
48 | unsigned short le16_to_cpu(unsigned short x) | ||
49 | { | ||
50 | return (((x & 0x00ff) << 8) | | ||
51 | ((x & 0xff00) >> 8)); | ||
52 | } | ||
53 | |||
54 | /* size of read buffer */ | ||
55 | #define SIZE 0x1000 | ||
56 | |||
57 | /* PPCBUG ROM boot header */ | ||
58 | typedef struct bug_boot_header { | ||
59 | uint8_t magic_word[4]; /* "BOOT" */ | ||
60 | uint32_t entry_offset; /* Offset from top of header to code */ | ||
61 | uint32_t routine_length; /* Length of code */ | ||
62 | uint8_t routine_name[8]; /* Name of the boot code */ | ||
63 | } bug_boot_header_t; | ||
64 | |||
65 | #define HEADER_SIZE sizeof(bug_boot_header_t) | ||
66 | |||
67 | uint32_t copy_image(int32_t in_fd, int32_t out_fd) | ||
68 | { | ||
69 | uint8_t buf[SIZE]; | ||
70 | int n; | ||
71 | uint32_t image_size = 0; | ||
72 | uint8_t zero = 0; | ||
73 | |||
74 | lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET); | ||
75 | |||
76 | /* Copy an image while recording its size */ | ||
77 | while ( (n = read(in_fd, buf, SIZE)) > 0 ) | ||
78 | { | ||
79 | image_size = image_size + n; | ||
80 | write(out_fd, buf, n); | ||
81 | } | ||
82 | |||
83 | /* BUG romboot requires that our size is divisible by 2 */ | ||
84 | /* align image to 2 byte boundary */ | ||
85 | if (image_size % 2) | ||
86 | { | ||
87 | image_size++; | ||
88 | write(out_fd, &zero, 1); | ||
89 | } | ||
90 | |||
91 | return image_size; | ||
92 | } | ||
93 | |||
94 | void write_bugboot_header(int32_t out_fd, uint32_t boot_size) | ||
95 | { | ||
96 | uint8_t header_block[HEADER_SIZE]; | ||
97 | bug_boot_header_t *bbh = (bug_boot_header_t *)&header_block[0]; | ||
98 | |||
99 | memset(header_block, 0, HEADER_SIZE); | ||
100 | |||
101 | /* Fill in the PPCBUG ROM boot header */ | ||
102 | strncpy(bbh->magic_word, "BOOT", 4); /* PPCBUG magic word */ | ||
103 | bbh->entry_offset = cpu_to_be32(HEADER_SIZE); /* Entry address */ | ||
104 | bbh->routine_length= cpu_to_be32(HEADER_SIZE+boot_size+2); /* Routine length */ | ||
105 | strncpy(bbh->routine_name, "LINUXROM", 8); /* Routine name */ | ||
106 | |||
107 | /* Output the header and bootloader to the file */ | ||
108 | write(out_fd, header_block, HEADER_SIZE); | ||
109 | } | ||
110 | |||
111 | uint16_t calc_checksum(int32_t bug_fd) | ||
112 | { | ||
113 | uint32_t checksum_var = 0; | ||
114 | uint8_t buf[2]; | ||
115 | int n; | ||
116 | |||
117 | /* Checksum loop */ | ||
118 | while ( (n = read(bug_fd, buf, 2) ) ) | ||
119 | { | ||
120 | checksum_var = checksum_var + *(uint16_t *)buf; | ||
121 | |||
122 | /* If we carry out, mask it and add one to the checksum */ | ||
123 | if (checksum_var >> 16) | ||
124 | checksum_var = (checksum_var & 0x0000ffff) + 1; | ||
125 | } | ||
126 | |||
127 | return checksum_var; | ||
128 | } | ||
129 | |||
130 | int main(int argc, char *argv[]) | ||
131 | { | ||
132 | int32_t image_fd, bugboot_fd; | ||
133 | int argptr = 1; | ||
134 | uint32_t kernel_size = 0; | ||
135 | uint16_t checksum = 0; | ||
136 | uint8_t bugbootname[256]; | ||
137 | |||
138 | if ( (argc != 3) ) | ||
139 | { | ||
140 | fprintf(stderr, "usage: %s <kernel_image> <bugboot>\n",argv[0]); | ||
141 | exit(-1); | ||
142 | } | ||
143 | |||
144 | /* Get file args */ | ||
145 | |||
146 | /* kernel image file */ | ||
147 | if ((image_fd = open( argv[argptr] , 0)) < 0) | ||
148 | exit(-1); | ||
149 | argptr++; | ||
150 | |||
151 | /* bugboot file */ | ||
152 | if ( !strcmp( argv[argptr], "-" ) ) | ||
153 | bugboot_fd = 1; /* stdout */ | ||
154 | else | ||
155 | if ((bugboot_fd = creat( argv[argptr] , 0755)) < 0) | ||
156 | exit(-1); | ||
157 | else | ||
158 | strcpy(bugbootname, argv[argptr]); | ||
159 | argptr++; | ||
160 | |||
161 | /* Set file position after ROM header block where zImage will be written */ | ||
162 | lseek(bugboot_fd, HEADER_SIZE, SEEK_SET); | ||
163 | |||
164 | /* Copy kernel image into bugboot image */ | ||
165 | kernel_size = copy_image(image_fd, bugboot_fd); | ||
166 | close(image_fd); | ||
167 | |||
168 | /* Set file position to beginning where header/romboot will be written */ | ||
169 | lseek(bugboot_fd, 0, SEEK_SET); | ||
170 | |||
171 | /* Write out BUG header/romboot */ | ||
172 | write_bugboot_header(bugboot_fd, kernel_size); | ||
173 | |||
174 | /* Close bugboot file */ | ||
175 | close(bugboot_fd); | ||
176 | |||
177 | /* Reopen it as read/write */ | ||
178 | bugboot_fd = open(bugbootname, O_RDWR); | ||
179 | |||
180 | /* Calculate checksum */ | ||
181 | checksum = calc_checksum(bugboot_fd); | ||
182 | |||
183 | /* Write out the calculated checksum */ | ||
184 | write(bugboot_fd, &checksum, 2); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
diff --git a/arch/ppc/boot/utils/mknote.c b/arch/ppc/boot/utils/mknote.c new file mode 100644 index 000000000000..b9fbb2cbfc8f --- /dev/null +++ b/arch/ppc/boot/utils/mknote.c | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * Copyright (C) Cort Dougan 1999. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * Generate a note section as per the CHRP specification. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <stdio.h> | ||
14 | #include <string.h> | ||
15 | |||
16 | #define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff ); | ||
17 | |||
18 | int main(void) | ||
19 | { | ||
20 | /* header */ | ||
21 | /* namesz */ | ||
22 | PL(strlen("PowerPC")+1); | ||
23 | /* descrsz */ | ||
24 | PL(6*4); | ||
25 | /* type */ | ||
26 | PL(0x1275); | ||
27 | /* name */ | ||
28 | printf("PowerPC"); printf("%c", 0); | ||
29 | |||
30 | /* descriptor */ | ||
31 | /* real-mode */ | ||
32 | PL(0xffffffff); | ||
33 | /* real-base */ | ||
34 | PL(0x00c00000); | ||
35 | /* real-size */ | ||
36 | PL(0xffffffff); | ||
37 | /* virt-base */ | ||
38 | PL(0xffffffff); | ||
39 | /* virt-size */ | ||
40 | PL(0xffffffff); | ||
41 | /* load-base */ | ||
42 | PL(0x4000); | ||
43 | return 0; | ||
44 | } | ||
diff --git a/arch/ppc/boot/utils/mkprep.c b/arch/ppc/boot/utils/mkprep.c new file mode 100644 index 000000000000..f6d5a2f2fcf6 --- /dev/null +++ b/arch/ppc/boot/utils/mkprep.c | |||
@@ -0,0 +1,293 @@ | |||
1 | /* | ||
2 | * Makes a prep bootable image which can be dd'd onto | ||
3 | * a disk device to make a bootdisk. Will take | ||
4 | * as input a elf executable, strip off the header | ||
5 | * and write out a boot image as: | ||
6 | * 1) default - strips elf header | ||
7 | * suitable as a network boot image | ||
8 | * 2) -pbp - strips elf header and writes out prep boot partition image | ||
9 | * cat or dd onto disk for booting | ||
10 | * 3) -asm - strips elf header and writes out as asm data | ||
11 | * useful for generating data for a compressed image | ||
12 | * -- Cort | ||
13 | * | ||
14 | * Modified for x86 hosted builds by Matt Porter <porter@neta.com> | ||
15 | * Modified for Sparc hosted builds by Peter Wahl <PeterWahl@web.de> | ||
16 | */ | ||
17 | |||
18 | #include <fcntl.h> | ||
19 | #include <stdio.h> | ||
20 | #include <stdlib.h> | ||
21 | #include <string.h> | ||
22 | #include <strings.h> | ||
23 | #include <sys/stat.h> | ||
24 | #include <unistd.h> | ||
25 | |||
26 | #define cpu_to_le32(x) le32_to_cpu((x)) | ||
27 | unsigned long le32_to_cpu(unsigned long x) | ||
28 | { | ||
29 | return (((x & 0x000000ffU) << 24) | | ||
30 | ((x & 0x0000ff00U) << 8) | | ||
31 | ((x & 0x00ff0000U) >> 8) | | ||
32 | ((x & 0xff000000U) >> 24)); | ||
33 | } | ||
34 | |||
35 | |||
36 | #define cpu_to_le16(x) le16_to_cpu((x)) | ||
37 | unsigned short le16_to_cpu(unsigned short x) | ||
38 | { | ||
39 | return (((x & 0x00ff) << 8) | | ||
40 | ((x & 0xff00) >> 8)); | ||
41 | } | ||
42 | |||
43 | #define cpu_to_be32(x) (x) | ||
44 | #define be32_to_cpu(x) (x) | ||
45 | #define cpu_to_be16(x) (x) | ||
46 | #define be16_to_cpu(x) (x) | ||
47 | |||
48 | /* size of read buffer */ | ||
49 | #define SIZE 0x1000 | ||
50 | |||
51 | |||
52 | typedef unsigned long dword_t; | ||
53 | typedef unsigned short word_t; | ||
54 | typedef unsigned char byte_t; | ||
55 | typedef byte_t block_t[512]; | ||
56 | typedef byte_t page_t[4096]; | ||
57 | |||
58 | |||
59 | /* | ||
60 | * Partition table entry | ||
61 | * - from the PReP spec | ||
62 | */ | ||
63 | typedef struct partition_entry { | ||
64 | byte_t boot_indicator; | ||
65 | byte_t starting_head; | ||
66 | byte_t starting_sector; | ||
67 | byte_t starting_cylinder; | ||
68 | |||
69 | byte_t system_indicator; | ||
70 | byte_t ending_head; | ||
71 | byte_t ending_sector; | ||
72 | byte_t ending_cylinder; | ||
73 | |||
74 | dword_t beginning_sector; | ||
75 | dword_t number_of_sectors; | ||
76 | } partition_entry_t; | ||
77 | |||
78 | #define BootActive 0x80 | ||
79 | #define SystemPrep 0x41 | ||
80 | |||
81 | void copy_image(int , int); | ||
82 | void write_prep_partition(int , int ); | ||
83 | void write_asm_data( int in, int out ); | ||
84 | |||
85 | unsigned int elfhdr_size = 65536; | ||
86 | |||
87 | int main(int argc, char *argv[]) | ||
88 | { | ||
89 | int in_fd, out_fd; | ||
90 | int argptr = 1; | ||
91 | unsigned int prep = 0; | ||
92 | unsigned int asmoutput = 0; | ||
93 | |||
94 | if ( (argc < 3) || (argc > 4) ) | ||
95 | { | ||
96 | fprintf(stderr, "usage: %s [-pbp] [-asm] <boot-file> <image>\n",argv[0]); | ||
97 | exit(-1); | ||
98 | } | ||
99 | |||
100 | /* needs to handle args more elegantly -- but this is a small/simple program */ | ||
101 | |||
102 | /* check for -pbp */ | ||
103 | if ( !strcmp( argv[argptr], "-pbp" ) ) | ||
104 | { | ||
105 | prep = 1; | ||
106 | argptr++; | ||
107 | } | ||
108 | |||
109 | /* check for -asm */ | ||
110 | if ( !strcmp( argv[argptr], "-asm" ) ) | ||
111 | { | ||
112 | asmoutput = 1; | ||
113 | argptr++; | ||
114 | } | ||
115 | |||
116 | /* input file */ | ||
117 | if ( !strcmp( argv[argptr], "-" ) ) | ||
118 | in_fd = 0; /* stdin */ | ||
119 | else | ||
120 | if ((in_fd = open( argv[argptr] , 0)) < 0) | ||
121 | exit(-1); | ||
122 | argptr++; | ||
123 | |||
124 | /* output file */ | ||
125 | if ( !strcmp( argv[argptr], "-" ) ) | ||
126 | out_fd = 1; /* stdout */ | ||
127 | else | ||
128 | if ((out_fd = creat( argv[argptr] , 0755)) < 0) | ||
129 | exit(-1); | ||
130 | argptr++; | ||
131 | |||
132 | /* skip elf header in input file */ | ||
133 | /*if ( !prep )*/ | ||
134 | lseek(in_fd, elfhdr_size, SEEK_SET); | ||
135 | |||
136 | /* write prep partition if necessary */ | ||
137 | if ( prep ) | ||
138 | write_prep_partition( in_fd, out_fd ); | ||
139 | |||
140 | /* write input image to bootimage */ | ||
141 | if ( asmoutput ) | ||
142 | write_asm_data( in_fd, out_fd ); | ||
143 | else | ||
144 | copy_image(in_fd, out_fd); | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | void write_prep_partition(int in, int out) | ||
150 | { | ||
151 | unsigned char block[512]; | ||
152 | partition_entry_t pe; | ||
153 | dword_t *entry = (dword_t *)&block[0]; | ||
154 | dword_t *length = (dword_t *)&block[sizeof(long)]; | ||
155 | struct stat info; | ||
156 | |||
157 | if (fstat(in, &info) < 0) | ||
158 | { | ||
159 | fprintf(stderr,"info failed\n"); | ||
160 | exit(-1); | ||
161 | } | ||
162 | |||
163 | bzero( block, sizeof block ); | ||
164 | |||
165 | /* set entry point and boot image size skipping over elf header */ | ||
166 | #ifdef __i386__ | ||
167 | *entry = 0x400/*+65536*/; | ||
168 | *length = info.st_size-elfhdr_size+0x400; | ||
169 | #else | ||
170 | *entry = cpu_to_le32(0x400/*+65536*/); | ||
171 | *length = cpu_to_le32(info.st_size-elfhdr_size+0x400); | ||
172 | #endif /* __i386__ */ | ||
173 | |||
174 | /* sets magic number for msdos partition (used by linux) */ | ||
175 | block[510] = 0x55; | ||
176 | block[511] = 0xAA; | ||
177 | |||
178 | /* | ||
179 | * Build a "PReP" partition table entry in the boot record | ||
180 | * - "PReP" may only look at the system_indicator | ||
181 | */ | ||
182 | pe.boot_indicator = BootActive; | ||
183 | pe.system_indicator = SystemPrep; | ||
184 | /* | ||
185 | * The first block of the diskette is used by this "boot record" which | ||
186 | * actually contains the partition table. (The first block of the | ||
187 | * partition contains the boot image, but I digress...) We'll set up | ||
188 | * one partition on the diskette and it shall contain the rest of the | ||
189 | * diskette. | ||
190 | */ | ||
191 | pe.starting_head = 0; /* zero-based */ | ||
192 | pe.starting_sector = 2; /* one-based */ | ||
193 | pe.starting_cylinder = 0; /* zero-based */ | ||
194 | pe.ending_head = 1; /* assumes two heads */ | ||
195 | pe.ending_sector = 18; /* assumes 18 sectors/track */ | ||
196 | pe.ending_cylinder = 79; /* assumes 80 cylinders/diskette */ | ||
197 | |||
198 | /* | ||
199 | * The "PReP" software ignores the above fields and just looks at | ||
200 | * the next two. | ||
201 | * - size of the diskette is (assumed to be) | ||
202 | * (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette) | ||
203 | * - unlike the above sector numbers, the beginning sector is zero-based! | ||
204 | */ | ||
205 | #if 0 | ||
206 | pe.beginning_sector = cpu_to_le32(1); | ||
207 | #else | ||
208 | /* This has to be 0 on the PowerStack? */ | ||
209 | #ifdef __i386__ | ||
210 | pe.beginning_sector = 0; | ||
211 | #else | ||
212 | pe.beginning_sector = cpu_to_le32(0); | ||
213 | #endif /* __i386__ */ | ||
214 | #endif | ||
215 | |||
216 | #ifdef __i386__ | ||
217 | pe.number_of_sectors = 2*18*80-1; | ||
218 | #else | ||
219 | pe.number_of_sectors = cpu_to_le32(2*18*80-1); | ||
220 | #endif /* __i386__ */ | ||
221 | |||
222 | memcpy(&block[0x1BE], &pe, sizeof(pe)); | ||
223 | |||
224 | write( out, block, sizeof(block) ); | ||
225 | write( out, entry, sizeof(*entry) ); | ||
226 | write( out, length, sizeof(*length) ); | ||
227 | /* set file position to 2nd sector where image will be written */ | ||
228 | lseek( out, 0x400, SEEK_SET ); | ||
229 | } | ||
230 | |||
231 | |||
232 | |||
233 | void | ||
234 | copy_image(int in, int out) | ||
235 | { | ||
236 | char buf[SIZE]; | ||
237 | int n; | ||
238 | |||
239 | while ( (n = read(in, buf, SIZE)) > 0 ) | ||
240 | write(out, buf, n); | ||
241 | } | ||
242 | |||
243 | |||
244 | void | ||
245 | write_asm_data( int in, int out ) | ||
246 | { | ||
247 | int i, cnt, pos, len; | ||
248 | unsigned int cksum, val; | ||
249 | unsigned char *lp; | ||
250 | unsigned char buf[SIZE]; | ||
251 | unsigned char str[256]; | ||
252 | |||
253 | write( out, "\t.data\n\t.globl input_data\ninput_data:\n", | ||
254 | strlen( "\t.data\n\t.globl input_data\ninput_data:\n" ) ); | ||
255 | pos = 0; | ||
256 | cksum = 0; | ||
257 | while ((len = read(in, buf, sizeof(buf))) > 0) | ||
258 | { | ||
259 | cnt = 0; | ||
260 | lp = (unsigned char *)buf; | ||
261 | len = (len + 3) & ~3; /* Round up to longwords */ | ||
262 | for (i = 0; i < len; i += 4) | ||
263 | { | ||
264 | if (cnt == 0) | ||
265 | { | ||
266 | write( out, "\t.long\t", strlen( "\t.long\t" ) ); | ||
267 | } | ||
268 | sprintf( str, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); | ||
269 | write( out, str, strlen(str) ); | ||
270 | val = *(unsigned long *)lp; | ||
271 | cksum ^= val; | ||
272 | lp += 4; | ||
273 | if (++cnt == 4) | ||
274 | { | ||
275 | cnt = 0; | ||
276 | sprintf( str, " # %x \n", pos+i-12); | ||
277 | write( out, str, strlen(str) ); | ||
278 | } else | ||
279 | { | ||
280 | write( out, ",", 1 ); | ||
281 | } | ||
282 | } | ||
283 | if (cnt) | ||
284 | { | ||
285 | write( out, "0\n", 2 ); | ||
286 | } | ||
287 | pos += len; | ||
288 | } | ||
289 | sprintf(str, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos); | ||
290 | write( out, str, strlen(str) ); | ||
291 | |||
292 | fprintf(stderr, "cksum = %x\n", cksum); | ||
293 | } | ||
diff --git a/arch/ppc/boot/utils/mktree.c b/arch/ppc/boot/utils/mktree.c new file mode 100644 index 000000000000..2be22e28f2b3 --- /dev/null +++ b/arch/ppc/boot/utils/mktree.c | |||
@@ -0,0 +1,152 @@ | |||
1 | /* | ||
2 | * Makes a tree bootable image for IBM Evaluation boards. | ||
3 | * Basically, just take a zImage, skip the ELF header, and stuff | ||
4 | * a 32 byte header on the front. | ||
5 | * | ||
6 | * We use htonl, which is a network macro, to make sure we're doing | ||
7 | * The Right Thing on an LE machine. It's non-obvious, but it should | ||
8 | * work on anything BSD'ish. | ||
9 | */ | ||
10 | |||
11 | #include <fcntl.h> | ||
12 | #include <stdio.h> | ||
13 | #include <stdlib.h> | ||
14 | #include <string.h> | ||
15 | #include <sys/stat.h> | ||
16 | #include <unistd.h> | ||
17 | #include <netinet/in.h> | ||
18 | #ifdef __sun__ | ||
19 | #include <inttypes.h> | ||
20 | #else | ||
21 | #include <stdint.h> | ||
22 | #endif | ||
23 | |||
24 | /* This gets tacked on the front of the image. There are also a few | ||
25 | * bytes allocated after the _start label used by the boot rom (see | ||
26 | * head.S for details). | ||
27 | */ | ||
28 | typedef struct boot_block { | ||
29 | uint32_t bb_magic; /* 0x0052504F */ | ||
30 | uint32_t bb_dest; /* Target address of the image */ | ||
31 | uint32_t bb_num_512blocks; /* Size, rounded-up, in 512 byte blks */ | ||
32 | uint32_t bb_debug_flag; /* Run debugger or image after load */ | ||
33 | uint32_t bb_entry_point; /* The image address to start */ | ||
34 | uint32_t bb_checksum; /* 32 bit checksum including header */ | ||
35 | uint32_t reserved[2]; | ||
36 | } boot_block_t; | ||
37 | |||
38 | #define IMGBLK 512 | ||
39 | char tmpbuf[IMGBLK]; | ||
40 | |||
41 | int main(int argc, char *argv[]) | ||
42 | { | ||
43 | int in_fd, out_fd; | ||
44 | int nblks, i; | ||
45 | uint cksum, *cp; | ||
46 | struct stat st; | ||
47 | boot_block_t bt; | ||
48 | |||
49 | if (argc < 3) { | ||
50 | fprintf(stderr, "usage: %s <zImage-file> <boot-image> [entry-point]\n",argv[0]); | ||
51 | exit(1); | ||
52 | } | ||
53 | |||
54 | if (stat(argv[1], &st) < 0) { | ||
55 | perror("stat"); | ||
56 | exit(2); | ||
57 | } | ||
58 | |||
59 | nblks = (st.st_size + IMGBLK) / IMGBLK; | ||
60 | |||
61 | bt.bb_magic = htonl(0x0052504F); | ||
62 | |||
63 | /* If we have the optional entry point parameter, use it */ | ||
64 | if (argc == 4) | ||
65 | bt.bb_dest = bt.bb_entry_point = htonl(strtoul(argv[3], NULL, 0)); | ||
66 | else | ||
67 | bt.bb_dest = bt.bb_entry_point = htonl(0x500000); | ||
68 | |||
69 | /* We know these from the linker command. | ||
70 | * ...and then move it up into memory a little more so the | ||
71 | * relocation can happen. | ||
72 | */ | ||
73 | bt.bb_num_512blocks = htonl(nblks); | ||
74 | bt.bb_debug_flag = 0; | ||
75 | |||
76 | bt.bb_checksum = 0; | ||
77 | |||
78 | /* To be neat and tidy :-). | ||
79 | */ | ||
80 | bt.reserved[0] = 0; | ||
81 | bt.reserved[1] = 0; | ||
82 | |||
83 | if ((in_fd = open(argv[1], O_RDONLY)) < 0) { | ||
84 | perror("zImage open"); | ||
85 | exit(3); | ||
86 | } | ||
87 | |||
88 | if ((out_fd = open(argv[2], (O_RDWR | O_CREAT | O_TRUNC), 0666)) < 0) { | ||
89 | perror("bootfile open"); | ||
90 | exit(3); | ||
91 | } | ||
92 | |||
93 | cksum = 0; | ||
94 | cp = (void *)&bt; | ||
95 | for (i=0; i<sizeof(bt)/sizeof(uint); i++) | ||
96 | cksum += *cp++; | ||
97 | |||
98 | /* Assume zImage is an ELF file, and skip the 64K header. | ||
99 | */ | ||
100 | if (read(in_fd, tmpbuf, IMGBLK) != IMGBLK) { | ||
101 | fprintf(stderr, "%s is too small to be an ELF image\n", | ||
102 | argv[1]); | ||
103 | exit(4); | ||
104 | } | ||
105 | |||
106 | if ((*(uint *)tmpbuf) != htonl(0x7f454c46)) { | ||
107 | fprintf(stderr, "%s is not an ELF image\n", argv[1]); | ||
108 | exit(4); | ||
109 | } | ||
110 | |||
111 | if (lseek(in_fd, (64 * 1024), SEEK_SET) < 0) { | ||
112 | fprintf(stderr, "%s failed to seek in ELF image\n", argv[1]); | ||
113 | exit(4); | ||
114 | } | ||
115 | |||
116 | nblks -= (64 * 1024) / IMGBLK; | ||
117 | |||
118 | /* And away we go...... | ||
119 | */ | ||
120 | if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) { | ||
121 | perror("boot-image write"); | ||
122 | exit(5); | ||
123 | } | ||
124 | |||
125 | while (nblks-- > 0) { | ||
126 | if (read(in_fd, tmpbuf, IMGBLK) < 0) { | ||
127 | perror("zImage read"); | ||
128 | exit(5); | ||
129 | } | ||
130 | cp = (uint *)tmpbuf; | ||
131 | for (i=0; i<sizeof(tmpbuf)/sizeof(uint); i++) | ||
132 | cksum += *cp++; | ||
133 | if (write(out_fd, tmpbuf, sizeof(tmpbuf)) != sizeof(tmpbuf)) { | ||
134 | perror("boot-image write"); | ||
135 | exit(5); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | /* rewrite the header with the computed checksum. | ||
140 | */ | ||
141 | bt.bb_checksum = htonl(cksum); | ||
142 | if (lseek(out_fd, 0, SEEK_SET) < 0) { | ||
143 | perror("rewrite seek"); | ||
144 | exit(1); | ||
145 | } | ||
146 | if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) { | ||
147 | perror("boot-image rewrite"); | ||
148 | exit(1); | ||
149 | } | ||
150 | |||
151 | exit(0); | ||
152 | } | ||