aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/boot
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /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')
-rw-r--r--arch/ppc/boot/Makefile34
-rw-r--r--arch/ppc/boot/common/Makefile13
-rw-r--r--arch/ppc/boot/common/bootinfo.c70
-rw-r--r--arch/ppc/boot/common/crt0.S81
-rw-r--r--arch/ppc/boot/common/misc-common.c553
-rw-r--r--arch/ppc/boot/common/ns16550.c99
-rw-r--r--arch/ppc/boot/common/serial_stub.c23
-rw-r--r--arch/ppc/boot/common/string.S150
-rw-r--r--arch/ppc/boot/common/util.S293
-rw-r--r--arch/ppc/boot/images/Makefile27
-rw-r--r--arch/ppc/boot/include/cpc700.h26
-rw-r--r--arch/ppc/boot/include/iso_font.h257
-rw-r--r--arch/ppc/boot/include/mpc10x.h65
-rw-r--r--arch/ppc/boot/include/mpsc_defs.h146
-rw-r--r--arch/ppc/boot/include/nonstdio.h34
-rw-r--r--arch/ppc/boot/include/of1275.h39
-rw-r--r--arch/ppc/boot/include/rs6000.h243
-rw-r--r--arch/ppc/boot/include/serial.h46
-rw-r--r--arch/ppc/boot/ld.script88
-rw-r--r--arch/ppc/boot/lib/Makefile23
-rw-r--r--arch/ppc/boot/lib/div64.S58
-rw-r--r--arch/ppc/boot/lib/kbd.c248
-rw-r--r--arch/ppc/boot/lib/vreset.c805
-rw-r--r--arch/ppc/boot/of1275/Makefile6
-rw-r--r--arch/ppc/boot/of1275/claim.c34
-rw-r--r--arch/ppc/boot/of1275/enter.c22
-rw-r--r--arch/ppc/boot/of1275/exit.c24
-rw-r--r--arch/ppc/boot/of1275/finddevice.c31
-rw-r--r--arch/ppc/boot/of1275/getprop.c37
-rw-r--r--arch/ppc/boot/of1275/map.c48
-rw-r--r--arch/ppc/boot/of1275/ofinit.c27
-rw-r--r--arch/ppc/boot/of1275/ofstdio.c32
-rw-r--r--arch/ppc/boot/of1275/read.c35
-rw-r--r--arch/ppc/boot/of1275/release.c30
-rw-r--r--arch/ppc/boot/of1275/write.c35
-rw-r--r--arch/ppc/boot/openfirmware/Makefile188
-rw-r--r--arch/ppc/boot/openfirmware/chrpmain.c101
-rw-r--r--arch/ppc/boot/openfirmware/coffmain.c101
-rw-r--r--arch/ppc/boot/openfirmware/common.c162
-rw-r--r--arch/ppc/boot/openfirmware/dummy.c4
-rw-r--r--arch/ppc/boot/openfirmware/misc.S67
-rw-r--r--arch/ppc/boot/openfirmware/newworldmain.c94
-rw-r--r--arch/ppc/boot/openfirmware/start.c172
-rw-r--r--arch/ppc/boot/simple/Makefile252
-rw-r--r--arch/ppc/boot/simple/chrpmap.c12
-rw-r--r--arch/ppc/boot/simple/clear.S19
-rw-r--r--arch/ppc/boot/simple/cpc700_memory.c36
-rw-r--r--arch/ppc/boot/simple/dummy.c4
-rw-r--r--arch/ppc/boot/simple/embed_config.c981
-rw-r--r--arch/ppc/boot/simple/head.S142
-rw-r--r--arch/ppc/boot/simple/iic.c214
-rw-r--r--arch/ppc/boot/simple/m8260_tty.c325
-rw-r--r--arch/ppc/boot/simple/m8xx_tty.c290
-rw-r--r--arch/ppc/boot/simple/misc-chestnut.c35
-rw-r--r--arch/ppc/boot/simple/misc-cpci690.c27
-rw-r--r--arch/ppc/boot/simple/misc-embedded.c275
-rw-r--r--arch/ppc/boot/simple/misc-ev64260.c57
-rw-r--r--arch/ppc/boot/simple/misc-katana.c37
-rw-r--r--arch/ppc/boot/simple/misc-mv64x60.c61
-rw-r--r--arch/ppc/boot/simple/misc-prep.c212
-rw-r--r--arch/ppc/boot/simple/misc-radstone_ppc7d.c26
-rw-r--r--arch/ppc/boot/simple/misc-spruce.c274
-rw-r--r--arch/ppc/boot/simple/misc.c284
-rw-r--r--arch/ppc/boot/simple/mpc10x_memory.c111
-rw-r--r--arch/ppc/boot/simple/mpc52xx_tty.c140
-rw-r--r--arch/ppc/boot/simple/mv64x60_tty.c360
-rw-r--r--arch/ppc/boot/simple/openbios.c37
-rw-r--r--arch/ppc/boot/simple/pci.c274
-rw-r--r--arch/ppc/boot/simple/pibs.c103
-rw-r--r--arch/ppc/boot/simple/prepmap.c12
-rw-r--r--arch/ppc/boot/simple/qspan_pci.c269
-rw-r--r--arch/ppc/boot/simple/relocate.S216
-rw-r--r--arch/ppc/boot/simple/rw4/ppc_40x.h664
-rw-r--r--arch/ppc/boot/simple/rw4/rw4_init.S78
-rw-r--r--arch/ppc/boot/simple/rw4/rw4_init_brd.S1125
-rw-r--r--arch/ppc/boot/simple/rw4/stb.h239
-rw-r--r--arch/ppc/boot/utils/addRamDisk.c203
-rw-r--r--arch/ppc/boot/utils/addSystemMap.c186
-rw-r--r--arch/ppc/boot/utils/addnote.c175
-rw-r--r--arch/ppc/boot/utils/elf.pl33
-rw-r--r--arch/ppc/boot/utils/hack-coff.c84
-rw-r--r--arch/ppc/boot/utils/mkbugboot.c187
-rw-r--r--arch/ppc/boot/utils/mknote.c44
-rw-r--r--arch/ppc/boot/utils/mkprep.c293
-rw-r--r--arch/ppc/boot/utils/mktree.c152
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
13CFLAGS += -fno-builtin -D__BOOTER__ -Iarch/$(ARCH)/boot/include
14HOSTCFLAGS += -Iarch/$(ARCH)/boot/include
15
16BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd
17
18bootdir-y := simple
19bootdir-$(CONFIG_PPC_OF) += openfirmware
20subdir-y := lib common images
21subdir-$(CONFIG_PPC_OF) += of1275
22
23# for cleaning
24subdir- += simple openfirmware
25
26hostprogs-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
11lib-y := string.o util.o misc-common.o \
12 serial_stub.o bootinfo.o
13lib-$(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
18static struct bi_record * birec = NULL;
19
20static 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
40void
41bootinfo_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
53void
54bootinfo_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
413: 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
651: stwu r0,4(r8) # Clear out a word
66 bdnz 1b # If we are not done yet, keep clearing
672:
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)
27extern void cursor(int x, int y);
28extern void scroll(void);
29extern char *vidmem;
30extern int lines, cols;
31extern int orig_x, orig_y;
32extern int keyb_present;
33extern int CRT_tstc(void);
34extern int CRT_getc(void);
35#else
36int cursor(int x, int y) {return 0;}
37void scroll(void) {}
38char vidmem[1];
39#define lines 0
40#define cols 0
41int orig_x = 0;
42int orig_y = 0;
43#define keyb_present 0
44int CRT_tstc(void) {return 0;}
45int CRT_getc(void) {return 0;}
46#endif
47
48extern char *avail_ram;
49extern char *end_avail;
50extern char _end[];
51
52void puts(const char *);
53void putc(const char c);
54void puthex(unsigned long val);
55void gunzip(void *, int, unsigned char *, int *);
56static int _cvt(unsigned long val, char *buf, long radix, char *digits);
57
58void _vprintk(void(*putc)(const char), const char *fmt0, va_list ap);
59unsigned 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)
64extern unsigned long com_port;
65
66extern int serial_tstc(unsigned long com_port);
67extern unsigned char serial_getc(unsigned long com_port);
68extern void serial_putc(unsigned long com_port, unsigned char c);
69#endif
70
71void pause(void)
72{
73 puts("pause\n");
74}
75
76void exit(void)
77{
78 puts("exit\n");
79 while(1);
80}
81
82int 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
96int 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
111void
112putc(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
156void 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
200void error(char *x)
201{
202 puts("\n\n");
203 puts(x);
204 puts("\n\n -- System halted");
205
206 while(1); /* Halt */
207}
208
209static 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
228void 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
275void
276puthex(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
293void
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
306void
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
441int
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
465void
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
513void
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
526void ISA_init(unsigned long base)
527{
528 ISA_io = (unsigned char *)base;
529}
530
531void
532outb(int port, unsigned char val)
533{
534 /* Ensure I/O operations complete */
535 __asm__ volatile("eieio");
536 ISA_io[port] = val;
537}
538
539unsigned char
540inb(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
16extern unsigned long ISA_io;
17
18static struct serial_state rs_table[RS_TABLE_SIZE] = {
19 SERIAL_PORT_DFNS /* Defined in <asm/serial.h> */
20};
21
22static int shift;
23
24unsigned 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
79void
80serial_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
87unsigned char
88serial_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
95int
96serial_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
14unsigned long __attribute__ ((weak))
15serial_init(int chan, void *ignored)
16{
17 return 0;
18}
19
20void __attribute__ ((weak))
21serial_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
20strlen:
21 addi r4,r3,-1
221: lbzu r0,1(r4)
23 cmpwi 0,r0,0
24 bne 1b
25 subf r3,r3,r4
26 blr
27
28 .globl memset
29memset:
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
431: stwu r4,4(r6)
44 bdnz 1b
456: andi. r5,r5,3
467: cmpwi 0,r5,0
47 beqlr
48 mtctr r5
49 addi r6,r6,3
508: stbu r4,1(r6)
51 bdnz 8b
52 blr
53
54 .globl memmove
55memmove:
56 cmplw 0,r3,r4
57 bgt backwards_memcpy
58 /* fall through */
59
60 .globl memcpy
61memcpy:
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
691: 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
752: cmplwi 0,r5,4
76 blt 3f
77 lwzu r0,4(r4)
78 addi r5,r5,-4
79 stwu r0,4(r6)
803: cmpwi 0,r5,0
81 beqlr
82 mtctr r5
83 addi r4,r4,3
84 addi r6,r6,3
854: lbzu r0,1(r4)
86 stbu r0,1(r6)
87 bdnz 4b
88 blr
895: subfic r0,r0,4
90 mtctr r0
916: 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
103backwards_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
1111: 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
1172: cmplwi 0,r5,4
118 blt 3f
119 lwzu r0,-4(r4)
120 subi r5,r5,4
121 stwu r0,-4(r6)
1223: cmpwi 0,r5,0
123 beqlr
124 mtctr r5
1254: lbzu r0,-1(r4)
126 stbu r0,-1(r6)
127 bdnz 4b
128 blr
1295: mtctr r0
1306: 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
140memcmp:
141 cmpwi 0,r5,0
142 blelr
143 mtctr r5
144 addi r6,r3,-1
145 addi r4,r4,-1
1461: 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
32disable_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
763: 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
83disable_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
1291: 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
1342: 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
1383: 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 */
1611: 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
184timebase_period_ns:
185 .long 60
186
187 .text
188/*
189 * Delay for a number of microseconds
190 */
191 .globl udelay
192udelay:
193 mfspr r4,SPRN_PVR
194 srwi r4,r4,16
195 cmpwi 0,r4,1 /* 601 ? */
196 bne .udelay_not_601
19700: li r0,86 /* Instructions / microsecond? */
198 mtctr r0
19910: 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 */
2151: 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
2222: mftbu r5
223 cmpw 0,r5,r8
224 blt 2b
225 bgt 3f
226 mftb r6
227 cmpw 0,r6,r9
228 blt 2b
2293: 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
2521: 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
28700: lwz r4,0(r3)
288 addi r3,r3,L1_CACHE_BYTES /* Next line, please */
289 bdnz 00b
29010: 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
5MKIMAGE := $(srctree)/scripts/mkuboot.sh
6
7extra-y := vmlinux.bin vmlinux.gz
8
9OBJCOPYFLAGS_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
16quiet_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
21targets += 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
27clean-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
19static inline long
20cpc700_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 @@
1static 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 */
13typedef int FILE;
14extern 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
22extern int getc(void);
23extern int printf(const char *format, ...);
24extern int sprintf(char *str, const char *format, ...);
25extern int tstc(void);
26extern void exit(void);
27extern void outb(int port, unsigned char val);
28extern void putc(const char c);
29extern void puthex(unsigned long val);
30extern void puts(const char *);
31extern void udelay(long delay);
32extern unsigned char inb(int port);
33extern void board_isa_init(void);
34extern 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
11typedef void *prom_handle;
12typedef void *ihandle;
13typedef void *phandle;
14typedef int (*prom_entry)(void *);
15
16#define OF_INVALID_HANDLE ((prom_handle)-1UL)
17
18extern prom_entry of_prom_entry;
19
20/* function declarations */
21
22void * claim(unsigned int virt, unsigned int size, unsigned int align);
23int map(unsigned int phys, unsigned int virt, unsigned int size);
24void enter(void);
25void exit(void);
26phandle finddevice(const char *name);
27int getprop(phandle node, const char *name, void *buf, int buflen);
28void ofinit(prom_entry entry);
29int ofstdio(ihandle *stdin, ihandle *stdout, ihandle *stderr);
30int read(ihandle instance, void *buf, int buflen);
31void release(void *virt, unsigned int size);
32int write(ihandle instance, void *buf, int buflen);
33
34/* inlines */
35
36extern 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
12struct 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
38typedef 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}
63AOUTHDR;
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
77struct 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 */
119struct 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
138struct 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
162union 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
228struct 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 */
24struct 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 @@
1OUTPUT_ARCH(powerpc)
2SECTIONS
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
5CFLAGS_kbd.o := -Idrivers/char
6CFLAGS_vreset.o := -I$(srctree)/arch/ppc/boot/include
7
8zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c
9
10lib-y += $(zlib:.c=.o) div64.o
11lib-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o
12
13
14# zlib files needs header from their original place
15EXTRA_CFLAGS += -Ilib/zlib_inflate
16
17quiet_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
23clean-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
301: 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
432: 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
493: 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
554: 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
6unsigned 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
14extern unsigned char inb(int port);
15extern void outb(int port, char val);
16extern void puts(const char *);
17extern void puthex(unsigned long val);
18extern void udelay(long x);
19
20static int kbd(int noblock)
21{
22 unsigned char dt, brk, val;
23 unsigned code;
24loop:
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)) {
66enter: /* 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
130static 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
202static 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
220static int kbd_reset = 0;
221
222static int key_pending = -1;
223
224int 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
239int 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
24extern char *vidmem;
25extern int lines, cols;
26struct VaRegs;
27
28/*
29 * VGA Register
30 */
31struct VgaRegs
32{
33 unsigned short io_port;
34 unsigned char io_index;
35 unsigned char io_value;
36};
37
38void unlockVideo(int slot);
39void setTextRegs(struct VgaRegs *svp);
40void setTextCLUT(int shift);
41void clearVideoMemory(void);
42void loadFont(unsigned char *ISA_mem);
43
44static 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
63struct 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
108struct 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 */
118struct 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
378unsigned 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
383static int scanPCI(int start_slt);
384static int PCIVendor(int);
385#ifdef DEBUG
386static void printslots(void);
387#endif
388extern void puthex(unsigned long);
389extern void puts(const char *);
390static void unlockS3(void);
391
392static inline void
393outw(int port, unsigned short val)
394{
395 outb(port, val >> 8);
396 outb(port+1, val);
397}
398
399int
400vga_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 */
491void
492writeAttr(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
503void
504setTextRegs(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
529void
530setTextCLUT(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
546void
547loadFont(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
577static void
578unlockS3(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 */
655void
656cursor(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
665void
666clearVideoMemory(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
689struct 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 */
710void
711unlockVideo(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
727long
728SwapBytes(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
744int
745scanPCI(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 */
776static
777int PCIVendor(int slotnum) {
778 struct PCI_ConfigInfo *pslot;
779
780 pslot = &PCI_slots[slotnum];
781
782return (pslot->regs[DEVID] & 0xFFFF);
783}
784
785#ifdef DEBUG
786static
787void 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
5lib-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
13void *
14claim(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
13void
14enter(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
13void
14exit(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
13phandle
14finddevice(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
13int
14getprop(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
14extern ihandle of_prom_mmu;
15
16int
17map(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
13prom_entry of_prom_entry;
14ihandle of_prom_mmu;
15
16void
17ofinit(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
13int
14ofstdio(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;
30err:
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
13int
14read(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
13void
14release(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
13int
14write(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
13zImage.initrd znetboot.initrd: del-ramdisk-sec := -R .ramdisk
14zImage.initrd znetboot.initrd: initrd := .initrd
15
16
17boot := arch/ppc/boot
18common := $(boot)/common
19utils := $(boot)/utils
20bootlib := $(boot)/lib
21of1275 := $(boot)/of1275
22images := $(boot)/images
23
24OBJCOPY_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
25COFF_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00500000 \
26 -Bstatic
27CHRP_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00800000
28NEWWORLD_LD_ARGS:= -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x01000000
29
30COMMONOBJS := start.o misc.o common.o
31COFFOBJS := coffcrt0.o $(COMMONOBJS) coffmain.o
32CHRPOBJS := crt0.o $(COMMONOBJS) chrpmain.o
33NEWWORLDOBJS := crt0.o $(COMMONOBJS) newworldmain.o
34
35targets := $(COFFOBJS) $(CHRPOBJS) $(NEWWORLDOBJS) dummy.o
36COFFOBJS := $(addprefix $(obj)/, $(COFFOBJS))
37CHRPOBJS := $(addprefix $(obj)/, $(CHRPOBJS))
38NEWWORLDOBJS := $(addprefix $(obj)/, $(NEWWORLDOBJS))
39
40LIBS := lib/lib.a $(bootlib)/lib.a $(of1275)/lib.a $(common)/lib.a
41
42HACKCOFF := $(utils)/hack-coff
43
44ifdef CONFIG_SMP
45END := .smp
46endif
47ifdef CONFIG_PPC64BRIDGE
48END += .64
49endif
50
51
52$(images)/ramdisk.image.gz:
53 @echo ' MISSING $@'
54 @echo ' RAM disk image must be provided separately'
55 @/bin/false
56
57objcpxmon-$(CONFIG_XMON) := --add-section=.sysmap=System.map \
58 --set-section-flags=.sysmap=contents,alloc,load,readonly,data
59quiet_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
65targets += 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.
70quiet_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
74targets += 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.
79quiet_cmd_mknote = MKNOTE $@
80 cmd_mknote = $(utils)/mknote > $@
81targets += 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
88targets += coffcrt0.o crt0.o
89$(obj)/coffcrt0.o $(obj)/crt0.o: $(common)/crt0.S FORCE
90 $(call if_changed_dep,as_o_S)
91
92quiet_cmd_gencoffb = COFF $@
93 cmd_gencoffb = $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) $< $(LIBS) && \
94 $(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec)
95targets += coffboot
96$(obj)/coffboot: $(obj)/image.o $(COFFOBJS) $(LIBS) $(srctree)/$(boot)/ld.script FORCE
97 $(call if_changed,gencoffb)
98targets += 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
104quiet_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
115quiet_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
129quiet_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
140quiet_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
146quiet_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
158zImage: $(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 ($<)'
164zImage.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
171TFTPIMAGE := /tftpboot/zImage
172
173.PHONY: znetboot znetboot.initrd
174znetboot: $(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 ($<)'
181znetboot.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 */
16extern char __image_begin, __image_end;
17extern char __ramdisk_begin, __ramdisk_end;
18extern char _start, _end;
19
20extern unsigned int heap_max;
21extern void flush_cache(void *, unsigned long);
22extern void gunzip(void *, int, unsigned char *, int *);
23extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
24 unsigned int progend);
25
26char *avail_ram;
27char *begin_avail, *end_avail;
28char *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
42static char scratch[SCRATCH_SIZE]; /* 1MB of scratch space for gunzip */
43
44typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int);
45
46void
47boot(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 */
17extern char __image_begin, __image_end;
18extern char __ramdisk_begin[], __ramdisk_end;
19extern char _start, _end;
20
21extern char image_data[], initrd_data[];
22extern int initrd_len, image_len;
23extern unsigned int heap_max;
24extern void flush_cache(void *start, unsigned int len);
25extern void gunzip(void *, int, unsigned char *, int *);
26extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
27 unsigned int progend);
28extern void setup_bats(unsigned long start);
29
30char *avail_ram;
31char *begin_avail, *end_avail;
32char *avail_high;
33
34#define SCRATCH_SIZE (128 << 10)
35
36static char heap[SCRATCH_SIZE];
37
38static unsigned long ram_start = 0;
39static unsigned long ram_end = 0x1000000;
40
41static unsigned long prog_start = 0x900000;
42static unsigned long prog_size = 0x700000;
43
44typedef void (*kernel_start_t)(int, int, void *);
45
46void 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 */
18extern char __sysmap_begin, __sysmap_end;
19
20extern int strcmp(const char *s1, const char *s2);
21extern char *avail_ram, *avail_high;
22extern char *end_avail;
23
24unsigned int heap_use, heap_max;
25
26struct memchunk {
27 unsigned int size;
28 struct memchunk *next;
29};
30
31static struct memchunk *freechunks;
32
33static 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
65void 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 */
116void 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 @@
1int 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
16setup_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
324: 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
465: 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
56flush_cache:
57 addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */
58 rlwinm. 4,4,27,5,31
59 mtctr 4
60 beqlr
611: 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 */
16extern char __image_begin, __image_end;
17extern char __ramdisk_begin[], __ramdisk_end;
18extern char _start, _end;
19
20extern unsigned int heap_max;
21extern void flush_cache(void *start, unsigned int len);
22extern void gunzip(void *, int, unsigned char *, int *);
23extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
24 unsigned int progend);
25
26char *avail_ram;
27char *begin_avail, *end_avail;
28char *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
38typedef void (*kernel_start_t)(int, int, void *);
39
40void 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
12extern int strlen(const char *s);
13extern void boot(int a1, int a2, void *prom);
14
15phandle stdin;
16phandle stdout;
17phandle stderr;
18
19void printk(char *fmt, ...);
20
21void
22start(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
33int 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
52int
53putc(int c, void *f)
54{
55 char ch = c;
56
57 return writestring(f, &ch, 1) == 1? c: -1;
58}
59
60int
61putchar(int c)
62{
63 return putc(c, stdout);
64}
65
66int
67fputs(char *str, void *f)
68{
69 int n = strlen(str);
70
71 return writestring(f, str, n) == n? 0: -1;
72}
73
74int
75readchar(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
90static char line[256];
91static char *lineptr;
92static int lineleft;
93
94int
95getchar(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
146extern int vsprintf(char *buf, const char *fmt, va_list args);
147static char sprint_buf[1024];
148
149void
150printk(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
161int
162printf(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
24boot := arch/ppc/boot
25common := $(boot)/common
26utils := $(boot)/utils
27bootlib := $(boot)/lib
28images := $(boot)/images
29of1275 := $(boot)/of1275
30tftpboot := /tftpboot
31
32# Normally, we use the 'misc.c' file for decompress_kernel and
33# whatnot. Sometimes we need to override this however.
34misc-y := misc.o
35
36# Normally, we have our images end in .elf, but something we want to
37# change this.
38end-y := elf
39
40# Additionally, we normally don't need to mess with the L2 / L3 caches
41# if present on 'classic' PPC.
42cacheflag-y := -DCLEAR_CACHES=""
43# This file will flush / disable the L2, and L3 if present.
44clear_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
51zimageinitrd-$(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
57zimageinitrd-$(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
65zimageinitrd-$(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
71zimageinitrd-$(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
77zimageinitrd-$(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
90zimageinitrd-$(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.
107motorola := $(CONFIG_MCPN765)$(CONFIG_MVME5100)$(CONFIG_PRPMC750) \
108$(CONFIG_PRPMC800)$(CONFIG_LOPEC)$(CONFIG_PPLUS)
109motorola := $(strip $(motorola))
110pcore := $(CONFIG_PCORE)$(CONFIG_POWERPMC250)
111
112 zimage-$(motorola) := zImage-PPLUS
113zimageinitrd-$(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
121zimageinitrd-$(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
127zimageinitrd-$(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
136zimageinitrd-$(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
142zimageinitrd-$(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)
152extra-aflags-$(CONFIG_REDWOOD_4) := -Wa,-m405
153extra.o-$(CONFIG_REDWOOD_4) := rw4/rw4_init.o rw4/rw4_init_brd.o
154EXTRA_AFLAGS := $(extra-aflags-y)
155# head.o needs to get the cacheflags defined.
156AFLAGS_head.o += $(cacheflag-y)
157
158# Linker args. This specifies where the image will be run at.
159LD_ARGS := -T $(srctree)/$(boot)/ld.script \
160 -Ttext $(CONFIG_BOOT_LOAD) -Bstatic
161OBJCOPY_ARGS := -O elf32-powerpc
162
163# head.o and relocate.o must be at the start.
164boot-y := head.o relocate.o $(extra.o-y) $(misc-y)
165boot-$(CONFIG_40x) += embed_config.o
166boot-$(CONFIG_8xx) += embed_config.o
167boot-$(CONFIG_8260) += embed_config.o
168boot-$(CONFIG_BSEIP) += iic.o
169boot-$(CONFIG_MBX) += iic.o pci.o qspan_pci.o
170boot-$(CONFIG_MV64X60) += misc-mv64x60.o
171boot-$(CONFIG_RPXCLASSIC) += iic.o pci.o qspan_pci.o
172boot-$(CONFIG_RPXLITE) += iic.o
173# Different boards need different serial implementations.
174ifeq ($(CONFIG_SERIAL_CPM_CONSOLE),y)
175boot-$(CONFIG_8xx) += m8xx_tty.o
176boot-$(CONFIG_8260) += m8260_tty.o
177endif
178boot-$(CONFIG_SERIAL_MPC52xx_CONSOLE) += mpc52xx_tty.o
179boot-$(CONFIG_SERIAL_MPSC_CONSOLE) += mv64x60_tty.o
180
181LIBS := $(common)/lib.a $(bootlib)/lib.a
182ifeq ($(CONFIG_PPC_PREP),y)
183LIBS += $(of1275)/lib.a
184endif
185
186OBJS := $(addprefix $(obj)/,$(boot-y))
187
188# Tools
189MKBUGBOOT := $(utils)/mkbugboot
190MKPREP := $(utils)/mkprep
191MKTREE := $(utils)/mktree
192
193targets := 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.
218zImage: $(images)/$(zimage-y) $(obj)/zvmlinux
219 cp -f $(obj)/zvmlinux $(images)/zImage.elf
220 rm -f $(obj)/zvmlinux
221
222zImage.initrd: $(images)/$(zimageinitrd-y) $(obj)/zvmlinux.initrd
223 cp -f $(obj)/zvmlinux.initrd $(images)/zImage.initrd.elf
224 rm -f $(obj)/zvmlinux.initrd
225
226znetboot: zImage
227 cp $(images)/zImage.$(end-y) $(tftpboot)/zImage.$(end-y)
228
229znetboot.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
9void 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
18unsigned long
19cpc700_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 @@
1int 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
24extern unsigned long timebase_period_ns;
25
26/* For those boards that don't provide one.
27*/
28#if !defined(CONFIG_MBX)
29static 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 */
36extern 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 */
42static 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 */
49void
50embed_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*/
105u_char
106aschex_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
139static void
140rpx_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
151static uint
152rpx_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)
168static void
169rpx_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
184static void
185rpx_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)
221static void
222rpx_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)
238static void
239rpx_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*/
261void
262embed_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 */
342void
343embed_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 */
376void
377embed_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 */
407static 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
413static void
414clk_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
449static 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
455static void
456clk_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
490void
491embed_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)
522void
523embed_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
559void
560embed_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
592void
593embed_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
679void
680embed_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
712void
713embed_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
746void
747embed_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
794static void
795get_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
802void
803embed_config(bd_t **bdp)
804{
805 *bdp = &bdinfo;
806 get_board_info(bdp);
807}
808#else /* !CONFIG_BEECH */
809void
810embed_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
869void
870embed_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 */
949void
950embed_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
36start:
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
48start_:
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
98haveOF:
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 */
15void iic_read(uint devaddr, u_char *buf, uint offset, uint count);
16
17static int iic_init_done;
18
19static void
20iic_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 */
111static u_char iitemp[32];
112
113void
114iic_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
9uint no_print;
10extern char *params[];
11extern int nparams;
12static u_char cons_hold[128], *sgptr;
13static 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
25unsigned long
26serial_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
223int
224serial_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
258void
259serial_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
289char
290serial_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
304int
305serial_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
26static 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
33static cpm8xx_t *cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
34
35unsigned long
36serial_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
239void
240serial_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
259char
260serial_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
280int
281serial_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
23void
24mv64x60_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
17extern u32 mv64x60_console_baud;
18extern u32 mv64x60_mpsc_clk_src;
19extern u32 mv64x60_mpsc_clk_freq;
20
21void
22mv64x60_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. */
27extern char __image_begin, __image_end;
28extern char __ramdisk_begin, __ramdisk_end;
29extern 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 */
39char cmd_buf[256];
40char *cmd_line = cmd_buf;
41char *avail_ram;
42char *end_avail;
43char *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 */
48char *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
54char compiled_string[] = CONFIG_CMDLINE;
55#endif
56char ramroot_string[] = "root=/dev/ram";
57char netroot_string[] = "root=/dev/nfs rw ip=on";
58
59/* Serial port to use. */
60unsigned 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 */
64bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
65bd_t *hold_residual = &hold_resid_buf;
66
67extern unsigned long serial_init(int chan, bd_t *bp);
68extern void serial_close(unsigned long com_port);
69extern unsigned long start;
70extern void flush_instruction_cache(void);
71extern void gunzip(void *, int, unsigned char *, int *);
72extern 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 */
77void __attribute__ ((weak))
78embed_config(bd_t **bdp)
79{
80}
81
82unsigned long
83load_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
23extern u32 mv64x60_console_baud;
24extern u32 mv64x60_mpsc_clk_src;
25extern u32 mv64x60_mpsc_clk_freq;
26#endif
27
28void
29mv64x60_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
20extern u32 mv64x60_console_baud;
21extern u32 mv64x60_mpsc_clk_src;
22extern 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
29void
30mv64x60_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
19extern struct bi_record *decompress_kernel(unsigned long load_addr,
20 int num_words, unsigned long cksum);
21
22void
23mv64x60_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
47void __attribute__ ((weak))
48mv64x60_board_init(void __iomem *old_base, void __iomem *new_base)
49{
50}
51
52void *
53load_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
19extern int keyb_present; /* keyboard controller is present by default */
20RESIDUAL hold_resid_buf;
21RESIDUAL *hold_residual = &hold_resid_buf;
22static void *OFW_interface; /* Pointer to OF, if available. */
23
24#ifdef CONFIG_VGA_CONSOLE
25char *vidmem = (char *)0xC00B8000;
26int lines = 25, cols = 80;
27int orig_x, orig_y = 24;
28#endif /* CONFIG_VGA_CONSOLE */
29
30extern int CRT_tstc(void);
31extern int vga_init(unsigned char *ISA_mem);
32extern void gunzip(void *, int, unsigned char *, int *);
33extern unsigned long serial_init(int chan, void *ignored);
34extern void serial_fixups(void);
35extern struct bi_record *decompress_kernel(unsigned long load_addr,
36 int num_words, unsigned long cksum);
37extern void disable_6xx_mmu(void);
38extern unsigned long mpc10x_get_mem_size(void);
39
40static void
41writel(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
51static void
52pci_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
67void
68scroll(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
78unsigned long
79load_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
163unsigned long
164get_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)
13extern u32 mv64x60_console_baud;
14extern u32 mv64x60_mpsc_clk_src;
15extern u32 mv64x60_mpsc_clk_freq;
16#endif
17
18void
19mv64x60_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
23extern 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. */
31unsigned int *pci_config_address = (unsigned int *)SPRUCE_PCI_CONFIG_ADDR;
32unsigned char *pci_config_data = (unsigned char *)SPRUCE_PCI_CONFIG_DATA;
33
34void 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
43void 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
52void 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
61void 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
70void 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
79void 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
109unsigned long
110get_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
173unsigned long
174load_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
59char *avail_ram;
60char *end_avail;
61char *zimage_start;
62char cmd_preset[] = CMDLINE;
63char cmd_buf[256];
64char *cmd_line = cmd_buf;
65int keyb_present = HAS_KEYB;
66int zimage_size;
67
68unsigned long com_port;
69unsigned long initrd_size = 0;
70
71/* The linker tells us various locations in the image */
72extern char __image_begin, __image_end;
73extern char __ramdisk_begin, __ramdisk_end;
74extern char _end[];
75/* Original location */
76extern unsigned long start;
77
78extern int CRT_tstc(void);
79extern unsigned long serial_init(int chan, void *ignored);
80extern void serial_close(unsigned long com_port);
81extern void gunzip(void *, int, unsigned char *, int *);
82extern void serial_fixups(void);
83
84/* Allow get_mem_size to be hooked into. This is the default. */
85unsigned long __attribute__ ((weak))
86get_mem_size(void)
87{
88 return 0;
89}
90
91struct bi_record *
92decompress_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
272void __attribute__ ((weak))
273board_isa_init(void)
274{
275}
276
277/* Allow decompress_kernel to be hooked into. This is the default. */
278void * __attribute__ ((weak))
279load_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) \
35static void \
36mpc10x_##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
47MPC10X_PCI_OP(read, byte, u8 *, in_8, 3)
48MPC10X_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
61unsigned long
62get_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
31static 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 */
41static int
42mpc52xx_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
67unsigned long
68serial_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
118void
119serial_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
128char
129serial_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
136int
137serial_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
25u32 mv64x60_console_baud = 9600;
26u32 mv64x60_mpsc_clk_src = 8; /* TCLK */
27u32 mv64x60_mpsc_clk_freq = 100000000;
28
29extern void udelay(long);
30static void stop_dma(int chan);
31
32static void __iomem *mv64x60_base = (void __iomem *)CONFIG_MV64X60_NEW_BASE;
33
34struct 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
45static 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
58static u32 mpsc_base[2] = { MV64x60_MPSC_0_OFFSET, MV64x60_MPSC_1_OFFSET };
59
60struct mv64x60_rx_desc {
61 u16 bufsize;
62 u16 bytecnt;
63 u32 cmd_stat;
64 u32 next_desc_ptr;
65 u32 buffer;
66};
67
68struct 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
85static struct mv64x60_rx_desc rd[2][RX_NUM_DESC] __attribute__ ((aligned(32)));
86static struct mv64x60_tx_desc td[2][TX_NUM_DESC] __attribute__ ((aligned(32)));
87
88static char rx_buf[2][RX_NUM_DESC * RX_BUF_SIZE] __attribute__ ((aligned(32)));
89static char tx_buf[2][TX_NUM_DESC * TX_BUF_SIZE] __attribute__ ((aligned(32)));
90
91static int cur_rd[2] = { 0, 0 };
92static int cur_td[2] = { 0, 0 };
93
94static 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
105static 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
112static 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
119static u32 dram_selects[MV64x60_CPU2MEM_WINDOWS] = { 0xe, 0xd, 0xb, 0x7 };
120#endif
121
122unsigned long
123serial_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
248static void
249stop_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
269static int
270wait_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
285void
286serial_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
310unsigned char
311serial_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
328int
329serial_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
356void
357serial_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
18extern 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. */
23bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
24bd_t *hold_residual = &hold_resid_buf;
25
26void *
27load_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
7extern void puthex(unsigned long val);
8extern 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 */
18typedef 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
28int pci_dev_cnt;
29pci_map_t pci_map[MAX_PCI_DEVS];
30
31void pci_conf_write(int bus, int device, int func, int reg, uint writeval);
32void pci_conf_read(int bus, int device, int func, int reg, void *readval);
33void probe_addresses(int bus, int devfn);
34void map_pci_addrs(void);
35
36extern int
37qs_pci_read_config_byte(unsigned char bus, unsigned char dev_fn,
38 unsigned char offset, unsigned char *val);
39extern int
40qs_pci_read_config_word(unsigned char bus, unsigned char dev_fn,
41 unsigned char offset, unsigned short *val);
42extern int
43qs_pci_read_config_dword(unsigned char bus, unsigned char dev_fn,
44 unsigned char offset, unsigned int *val);
45extern int
46qs_pci_write_config_byte(unsigned char bus, unsigned char dev_fn,
47 unsigned char offset, unsigned char val);
48extern int
49qs_pci_write_config_word(unsigned char bus, unsigned char dev_fn,
50 unsigned char offset, unsigned short val);
51extern int
52qs_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 */
59void
60pci_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 */
139void
140probe_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
186void
187map_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
15extern 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 */
20bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
21bd_t *hold_residual = &hold_resid_buf;
22
23/* String functions lifted from lib/vsprintf.c and lib/ctype.c */
24unsigned 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 */
410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
420,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 */
56unsigned 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
84void *
85load_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
9void 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*/
83void
84qspan_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
146int 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
169int 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
192int 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
207int 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
231int 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
255int 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
32relocate:
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
681:
69 mr r6, r5
702:
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
953: 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
113do_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
128do_relocate_from_start:
1291: 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
137do_relocate_from_end:
138 GETSYM(r3, end)
139 slwi r4,r7,2
140 add r4,r8,r4 /* Get the physical end */
1411: lwzu r5,-4(r4)
142 stwu r5, -4(r3)
143 xor r6,r6,r5
144 bdnz 1b
145
146do_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
158start_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
16750: stwu r0,4(r3)
168 cmpw cr0,r3,r4
169 bne 50b
17090: 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
551fprolog: macro f_name
552 .text
553 .align 2
554 .globl f_name
555f_name:
556 endm
557
558fepilog: 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#
13HdwInit:
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 +--------------------------------------------------------------------*/
205gcs_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
654hsmc0_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
763hsmc1_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
824ic_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
838ic_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
852ic_dcinv:
853 li r10,0 /* r10 <- line address */
854 li r11,DCACHE_NLINES /* r11 <- # lines in cache */
855 mtctr r11 /* set loop counter */
856
857ic_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 */
957gcs_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******************************************************************************/
1004hsmc_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
1010hsmc_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 +--------------------------------------------------------------------*/
1016try_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
1022try_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
1028try_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
1034try_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 +--------------------------------------------------------------------*/
1042hsmc_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
1050hsmc_cr_err: /* ERROR: SDRAM didn't reset*/
1051 li r3,-1 /* set RC=unsuccessful */
1052
1053hsmc_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******************************************************************************/
1078gcs_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 +--------------------------------------------------------------------*/
1086gcs_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 +--------------------------------------------------------------------*/
1101gcs_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 +--------------------------------------------------------------------*/
1118gcs_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
13void 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
21void put4k(FILE *file, char *buf )
22{
23 fwrite(buf, 1, 4096, file);
24}
25
26void death(const char *msg, FILE *fdesc, const char *fname)
27{
28 printf(msg);
29 fclose(fdesc);
30 unlink(fname);
31 exit(1);
32}
33
34int 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
7void 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
32void 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
40void put4k( /*ostream *outf*/FILE *file, char *buf )
41{
42 fwrite(buf, 1, 4096, file);
43}
44
45int 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
22char arch[] = "PowerPC";
23
24#define N_DESCR 6
25unsigned 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
45unsigned 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
76unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' };
77
78int 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
31int
32main(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
81readerr:
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))
39unsigned 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))
48unsigned 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 */
58typedef 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
67uint32_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
94void 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
111uint16_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
130int 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
18int 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))
27unsigned 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))
37unsigned 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
52typedef unsigned long dword_t;
53typedef unsigned short word_t;
54typedef unsigned char byte_t;
55typedef byte_t block_t[512];
56typedef byte_t page_t[4096];
57
58
59/*
60 * Partition table entry
61 * - from the PReP spec
62 */
63typedef 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
81void copy_image(int , int);
82void write_prep_partition(int , int );
83void write_asm_data( int in, int out );
84
85unsigned int elfhdr_size = 65536;
86
87int 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
149void 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
233void
234copy_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
244void
245write_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 */
28typedef 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
39char tmpbuf[IMGBLK];
40
41int 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}