diff options
Diffstat (limited to 'arch/ppc/boot/simple')
33 files changed, 7191 insertions, 0 deletions
diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile new file mode 100644 index 000000000000..d8d801fcee10 --- /dev/null +++ b/arch/ppc/boot/simple/Makefile | |||
@@ -0,0 +1,252 @@ | |||
1 | # This is far from simple, but I couldn't think of a good name. This is | ||
2 | # for making the 'zImage' or 'zImage.initrd' on a number of targets. | ||
3 | # | ||
4 | # Author: Tom Rini <trini@mvista.com> | ||
5 | # | ||
6 | # Notes: | ||
7 | # (1) For machines that do not want to use the ELF image directly (including | ||
8 | # stripping just the ELF header off), they must set the variables | ||
9 | # zimage-$(CONFIG_MACHINE) and zimagerd-$(CONFIG_MACHINE) to the target | ||
10 | # that produces the desired image and they must set end-$(CONFIG_MACHINE) | ||
11 | # to what will be suffixed to the image filename. | ||
12 | # (2) Regardless of (1), to have the resulting image be something other | ||
13 | # than 'zImage.elf', set end-$(CONFIG_MACHINE) to be the suffix used for | ||
14 | # the zImage, znetboot, and znetbootrd targets. | ||
15 | # (3) For machine targets which use the mktree program, you can optionally | ||
16 | # set entrypoint-$(CONFIG_MACHINE) to the location which the image should be | ||
17 | # loaded at. The optimal setting for entrypoint-$(CONFIG_MACHINE) is the link | ||
18 | # address. | ||
19 | # (4) It is advisable to pass in the memory size using BI_MEMSIZE and | ||
20 | # get_mem_size(), which is memory controller dependent. Add in the correct | ||
21 | # XXX_memory.o file for this to work, as well as editing the | ||
22 | # misc-$(CONFIG_MACHINE) variable. | ||
23 | |||
24 | boot := arch/ppc/boot | ||
25 | common := $(boot)/common | ||
26 | utils := $(boot)/utils | ||
27 | bootlib := $(boot)/lib | ||
28 | images := $(boot)/images | ||
29 | of1275 := $(boot)/of1275 | ||
30 | tftpboot := /tftpboot | ||
31 | |||
32 | # Normally, we use the 'misc.c' file for decompress_kernel and | ||
33 | # whatnot. Sometimes we need to override this however. | ||
34 | misc-y := misc.o | ||
35 | |||
36 | # Normally, we have our images end in .elf, but something we want to | ||
37 | # change this. | ||
38 | end-y := elf | ||
39 | |||
40 | # Additionally, we normally don't need to mess with the L2 / L3 caches | ||
41 | # if present on 'classic' PPC. | ||
42 | cacheflag-y := -DCLEAR_CACHES="" | ||
43 | # This file will flush / disable the L2, and L3 if present. | ||
44 | clear_L2_L3 := $(srctree)/$(boot)/simple/clear.S | ||
45 | |||
46 | # | ||
47 | # See arch/ppc/kconfig and arch/ppc/platforms/Kconfig | ||
48 | # for definition of what platform each config option refer to. | ||
49 | #---------------------------------------------------------------------------- | ||
50 | zimage-$(CONFIG_CPCI690) := zImage-STRIPELF | ||
51 | zimageinitrd-$(CONFIG_CPCI690) := zImage.initrd-STRIPELF | ||
52 | extra.o-$(CONFIG_CPCI690) := misc-cpci690.o | ||
53 | end-$(CONFIG_CPCI690) := cpci690 | ||
54 | cacheflag-$(CONFIG_CPCI690) := -include $(clear_L2_L3) | ||
55 | |||
56 | zimage-$(CONFIG_IBM_OPENBIOS) := zImage-TREE | ||
57 | zimageinitrd-$(CONFIG_IBM_OPENBIOS) := zImage.initrd-TREE | ||
58 | end-$(CONFIG_IBM_OPENBIOS) := treeboot | ||
59 | misc-$(CONFIG_IBM_OPENBIOS) := misc-embedded.o | ||
60 | |||
61 | end-$(CONFIG_EMBEDDEDBOOT) := embedded | ||
62 | misc-$(CONFIG_EMBEDDEDBOOT) := misc-embedded.o | ||
63 | |||
64 | zimage-$(CONFIG_EBONY) := zImage-TREE | ||
65 | zimageinitrd-$(CONFIG_EBONY) := zImage.initrd-TREE | ||
66 | end-$(CONFIG_EBONY) := ebony | ||
67 | entrypoint-$(CONFIG_EBONY) := 0x01000000 | ||
68 | extra.o-$(CONFIG_EBONY) := openbios.o | ||
69 | |||
70 | zimage-$(CONFIG_LUAN) := zImage-TREE | ||
71 | zimageinitrd-$(CONFIG_LUAN) := zImage.initrd-TREE | ||
72 | end-$(CONFIG_LUAN) := luan | ||
73 | entrypoint-$(CONFIG_LUAN) := 0x01000000 | ||
74 | extra.o-$(CONFIG_LUAN) := pibs.o | ||
75 | |||
76 | zimage-$(CONFIG_OCOTEA) := zImage-TREE | ||
77 | zimageinitrd-$(CONFIG_OCOTEA) := zImage.initrd-TREE | ||
78 | end-$(CONFIG_OCOTEA) := ocotea | ||
79 | entrypoint-$(CONFIG_OCOTEA) := 0x01000000 | ||
80 | extra.o-$(CONFIG_OCOTEA) := pibs.o | ||
81 | |||
82 | extra.o-$(CONFIG_EV64260) := misc-ev64260.o | ||
83 | end-$(CONFIG_EV64260) := ev64260 | ||
84 | cacheflag-$(CONFIG_EV64260) := -include $(clear_L2_L3) | ||
85 | |||
86 | extra.o-$(CONFIG_CHESTNUT) := misc-chestnut.o | ||
87 | end-$(CONFIG_CHESTNUT) := chestnut | ||
88 | |||
89 | zimage-$(CONFIG_GEMINI) := zImage-STRIPELF | ||
90 | zimageinitrd-$(CONFIG_GEMINI) := zImage.initrd-STRIPELF | ||
91 | end-$(CONFIG_GEMINI) := gemini | ||
92 | |||
93 | extra.o-$(CONFIG_K2) := prepmap.o | ||
94 | end-$(CONFIG_K2) := k2 | ||
95 | cacheflag-$(CONFIG_K2) := -include $(clear_L2_L3) | ||
96 | |||
97 | extra.o-$(CONFIG_KATANA) := misc-katana.o | ||
98 | end-$(CONFIG_KATANA) := katana | ||
99 | cacheflag-$(CONFIG_KATANA) := -include $(clear_L2_L3) | ||
100 | |||
101 | extra.o-$(CONFIG_RADSTONE_PPC7D) := misc-radstone_ppc7d.o | ||
102 | end-$(CONFIG_RADSTONE_PPC7D) := radstone_ppc7d | ||
103 | cacheflag-$(CONFIG_RADSTONE_PPC7D) := -include $(clear_L2_L3) | ||
104 | |||
105 | # kconfig 'feature', only one of these will ever be 'y' at a time. | ||
106 | # The rest will be unset. | ||
107 | motorola := $(CONFIG_MCPN765)$(CONFIG_MVME5100)$(CONFIG_PRPMC750) \ | ||
108 | $(CONFIG_PRPMC800)$(CONFIG_LOPEC)$(CONFIG_PPLUS) | ||
109 | motorola := $(strip $(motorola)) | ||
110 | pcore := $(CONFIG_PCORE)$(CONFIG_POWERPMC250) | ||
111 | |||
112 | zimage-$(motorola) := zImage-PPLUS | ||
113 | zimageinitrd-$(motorola) := zImage.initrd-PPLUS | ||
114 | end-$(motorola) := pplus | ||
115 | |||
116 | # Overrides previous assingment | ||
117 | extra.o-$(CONFIG_PPLUS) := prepmap.o | ||
118 | extra.o-$(CONFIG_LOPEC) := mpc10x_memory.o | ||
119 | |||
120 | zimage-$(pcore) := zImage-STRIPELF | ||
121 | zimageinitrd-$(pcore) := zImage.initrd-STRIPELF | ||
122 | extra.o-$(pcore) := chrpmap.o | ||
123 | end-$(pcore) := pcore | ||
124 | cacheflag-$(pcore) := -include $(clear_L2_L3) | ||
125 | |||
126 | zimage-$(CONFIG_PPC_PREP) := zImage-PPLUS | ||
127 | zimageinitrd-$(CONFIG_PPC_PREP) := zImage.initrd-PPLUS | ||
128 | extra.o-$(CONFIG_PPC_PREP) := prepmap.o | ||
129 | misc-$(CONFIG_PPC_PREP) += misc-prep.o mpc10x_memory.o | ||
130 | end-$(CONFIG_PPC_PREP) := prep | ||
131 | |||
132 | end-$(CONFIG_SANDPOINT) := sandpoint | ||
133 | cacheflag-$(CONFIG_SANDPOINT) := -include $(clear_L2_L3) | ||
134 | |||
135 | zimage-$(CONFIG_SPRUCE) := zImage-TREE | ||
136 | zimageinitrd-$(CONFIG_SPRUCE) := zImage.initrd-TREE | ||
137 | end-$(CONFIG_SPRUCE) := spruce | ||
138 | entrypoint-$(CONFIG_SPRUCE) := 0x00800000 | ||
139 | misc-$(CONFIG_SPRUCE) += misc-spruce.o | ||
140 | |||
141 | zimage-$(CONFIG_LITE5200) := zImage-STRIPELF | ||
142 | zimageinitrd-$(CONFIG_LITE5200) := zImage.initrd-STRIPELF | ||
143 | end-$(CONFIG_LITE5200) := lite5200 | ||
144 | cacheflag-$(CONFIG_LITE5200) := -include $(clear_L2_L3) | ||
145 | |||
146 | |||
147 | # SMP images should have a '.smp' suffix. | ||
148 | end-$(CONFIG_SMP) := $(end-y).smp | ||
149 | |||
150 | # This is a treeboot that needs init functions until the | ||
151 | # boot rom is sorted out (i.e. this is short lived) | ||
152 | extra-aflags-$(CONFIG_REDWOOD_4) := -Wa,-m405 | ||
153 | extra.o-$(CONFIG_REDWOOD_4) := rw4/rw4_init.o rw4/rw4_init_brd.o | ||
154 | EXTRA_AFLAGS := $(extra-aflags-y) | ||
155 | # head.o needs to get the cacheflags defined. | ||
156 | AFLAGS_head.o += $(cacheflag-y) | ||
157 | |||
158 | # Linker args. This specifies where the image will be run at. | ||
159 | LD_ARGS := -T $(srctree)/$(boot)/ld.script \ | ||
160 | -Ttext $(CONFIG_BOOT_LOAD) -Bstatic | ||
161 | OBJCOPY_ARGS := -O elf32-powerpc | ||
162 | |||
163 | # head.o and relocate.o must be at the start. | ||
164 | boot-y := head.o relocate.o $(extra.o-y) $(misc-y) | ||
165 | boot-$(CONFIG_40x) += embed_config.o | ||
166 | boot-$(CONFIG_8xx) += embed_config.o | ||
167 | boot-$(CONFIG_8260) += embed_config.o | ||
168 | boot-$(CONFIG_BSEIP) += iic.o | ||
169 | boot-$(CONFIG_MBX) += iic.o pci.o qspan_pci.o | ||
170 | boot-$(CONFIG_MV64X60) += misc-mv64x60.o | ||
171 | boot-$(CONFIG_RPXCLASSIC) += iic.o pci.o qspan_pci.o | ||
172 | boot-$(CONFIG_RPXLITE) += iic.o | ||
173 | # Different boards need different serial implementations. | ||
174 | ifeq ($(CONFIG_SERIAL_CPM_CONSOLE),y) | ||
175 | boot-$(CONFIG_8xx) += m8xx_tty.o | ||
176 | boot-$(CONFIG_8260) += m8260_tty.o | ||
177 | endif | ||
178 | boot-$(CONFIG_SERIAL_MPC52xx_CONSOLE) += mpc52xx_tty.o | ||
179 | boot-$(CONFIG_SERIAL_MPSC_CONSOLE) += mv64x60_tty.o | ||
180 | |||
181 | LIBS := $(common)/lib.a $(bootlib)/lib.a | ||
182 | ifeq ($(CONFIG_PPC_PREP),y) | ||
183 | LIBS += $(of1275)/lib.a | ||
184 | endif | ||
185 | |||
186 | OBJS := $(addprefix $(obj)/,$(boot-y)) | ||
187 | |||
188 | # Tools | ||
189 | MKBUGBOOT := $(utils)/mkbugboot | ||
190 | MKPREP := $(utils)/mkprep | ||
191 | MKTREE := $(utils)/mktree | ||
192 | |||
193 | targets := dummy.o | ||
194 | |||
195 | $(obj)/zvmlinux: $(OBJS) $(LIBS) $(srctree)/$(boot)/ld.script \ | ||
196 | $(images)/vmlinux.gz $(obj)/dummy.o | ||
197 | $(OBJCOPY) $(OBJCOPY_ARGS) \ | ||
198 | --add-section=.image=$(images)/vmlinux.gz \ | ||
199 | --set-section-flags=.image=contents,alloc,load,readonly,data \ | ||
200 | $(obj)/dummy.o $(obj)/image.o | ||
201 | $(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/image.o $(LIBS) | ||
202 | $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab \ | ||
203 | -R .stabstr -R .ramdisk -R .sysmap | ||
204 | |||
205 | $(obj)/zvmlinux.initrd: $(OBJS) $(LIBS) $(srctree)/$(boot)/ld.script \ | ||
206 | $(images)/vmlinux.gz $(obj)/dummy.o | ||
207 | $(OBJCOPY) $(OBJCOPY_ARGS) \ | ||
208 | --add-section=.ramdisk=$(images)/ramdisk.image.gz \ | ||
209 | --set-section-flags=.ramdisk=contents,alloc,load,readonly,data \ | ||
210 | --add-section=.image=$(images)/vmlinux.gz \ | ||
211 | --set-section-flags=.image=contents,alloc,load,readonly,data \ | ||
212 | $(obj)/dummy.o $(obj)/image.o | ||
213 | $(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/image.o $(LIBS) | ||
214 | $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab \ | ||
215 | -R .stabstr -R .sysmap | ||
216 | |||
217 | # Sort-of dummy rules, that let us format the image we want. | ||
218 | zImage: $(images)/$(zimage-y) $(obj)/zvmlinux | ||
219 | cp -f $(obj)/zvmlinux $(images)/zImage.elf | ||
220 | rm -f $(obj)/zvmlinux | ||
221 | |||
222 | zImage.initrd: $(images)/$(zimageinitrd-y) $(obj)/zvmlinux.initrd | ||
223 | cp -f $(obj)/zvmlinux.initrd $(images)/zImage.initrd.elf | ||
224 | rm -f $(obj)/zvmlinux.initrd | ||
225 | |||
226 | znetboot: zImage | ||
227 | cp $(images)/zImage.$(end-y) $(tftpboot)/zImage.$(end-y) | ||
228 | |||
229 | znetboot.initrd: zImage.initrd | ||
230 | cp $(images)/zImage.initrd.$(end-y) $(tftpboot)/zImage.initrd.$(end-y) | ||
231 | |||
232 | $(images)/zImage-STRIPELF: $(obj)/zvmlinux | ||
233 | dd if=$(obj)/zvmlinux of=$(images)/zImage.$(end-y) skip=64 bs=1k | ||
234 | |||
235 | $(images)/zImage.initrd-STRIPELF: $(obj)/zvmlinux.initrd | ||
236 | dd if=$(obj)/zvmlinux.initrd of=$(images)/zImage.initrd.$(end-y) \ | ||
237 | skip=64 bs=1k | ||
238 | |||
239 | $(images)/zImage-TREE: $(obj)/zvmlinux $(MKTREE) | ||
240 | $(MKTREE) $(obj)/zvmlinux $(images)/zImage.$(end-y) $(ENTRYPOINT) | ||
241 | |||
242 | $(images)/zImage.initrd-TREE: $(obj)/zvmlinux.initrd $(MKTREE) | ||
243 | $(MKTREE) $(obj)/zvmlinux.initrd $(images)/zImage.initrd.$(end-y) \ | ||
244 | $(ENTRYPOINT) | ||
245 | |||
246 | $(images)/zImage-PPLUS: $(obj)/zvmlinux $(MKPREP) $(MKBUGBOOT) | ||
247 | $(MKPREP) -pbp $(obj)/zvmlinux $(images)/zImage.$(end-y) | ||
248 | $(MKBUGBOOT) $(obj)/zvmlinux $(images)/zImage.bugboot | ||
249 | |||
250 | $(images)/zImage.initrd-PPLUS: $(obj)/zvmlinux.initrd $(MKPREP) $(MKBUGBOOT) | ||
251 | $(MKPREP) -pbp $(obj)/zvmlinux.initrd $(images)/zImage.initrd.$(end-y) | ||
252 | $(MKBUGBOOT) $(obj)/zvmlinux.initrd $(images)/zImage.initrd.bugboot | ||
diff --git a/arch/ppc/boot/simple/chrpmap.c b/arch/ppc/boot/simple/chrpmap.c new file mode 100644 index 000000000000..14d9e05d98bb --- /dev/null +++ b/arch/ppc/boot/simple/chrpmap.c | |||
@@ -0,0 +1,12 @@ | |||
1 | /* | ||
2 | * 2004 (C) IBM. This file is licensed under the terms of the GNU General | ||
3 | * Public License version 2. This program is licensed "as is" without any | ||
4 | * warranty of any kind, whether express or implied. | ||
5 | */ | ||
6 | |||
7 | #include <nonstdio.h> | ||
8 | |||
9 | void board_isa_init(void) | ||
10 | { | ||
11 | ISA_init(0xFE000000); | ||
12 | } | ||
diff --git a/arch/ppc/boot/simple/clear.S b/arch/ppc/boot/simple/clear.S new file mode 100644 index 000000000000..95c5647a0f51 --- /dev/null +++ b/arch/ppc/boot/simple/clear.S | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * Code to call _setup_L2CR to flus, invalidate and disable the L2, | ||
3 | * and if present, do the same to the L3. | ||
4 | */ | ||
5 | |||
6 | #define CLEAR_CACHES \ | ||
7 | bl _setup_L2CR; \ | ||
8 | \ | ||
9 | /* If 745x, turn off L3CR as well */ \ | ||
10 | mfspr r8,SPRN_PVR; \ | ||
11 | srwi r8,r8,16; \ | ||
12 | \ | ||
13 | cmpli cr0,r8,0x8000; /* 7450 */ \ | ||
14 | cmpli cr1,r8,0x8001; /* 7455 */ \ | ||
15 | cmpli cr2,r8,0x8002; /* 7457 */ \ | ||
16 | /* Now test if any are true. */ \ | ||
17 | cror 4*cr0+eq,4*cr0+eq,4*cr1+eq; \ | ||
18 | cror 4*cr0+eq,4*cr0+eq,4*cr2+eq; \ | ||
19 | beql _setup_L3CR | ||
diff --git a/arch/ppc/boot/simple/cpc700_memory.c b/arch/ppc/boot/simple/cpc700_memory.c new file mode 100644 index 000000000000..8c75cf6c2383 --- /dev/null +++ b/arch/ppc/boot/simple/cpc700_memory.c | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/common/cpc700_memory.c | ||
3 | * | ||
4 | * Find memory based upon settings in the CPC700 bridge | ||
5 | * | ||
6 | * Author: Dan Cox | ||
7 | * | ||
8 | * 2001-2002 (c) MontaVista, Software, Inc. This file is licensed under | ||
9 | * the terms of the GNU General Public License version 2. This program | ||
10 | * is licensed "as is" without any warranty of any kind, whether express | ||
11 | * or implied. | ||
12 | */ | ||
13 | |||
14 | #include <asm/types.h> | ||
15 | #include <asm/io.h> | ||
16 | #include "cpc700.h" | ||
17 | |||
18 | unsigned long | ||
19 | cpc700_get_mem_size(void) | ||
20 | { | ||
21 | int i; | ||
22 | unsigned long len, amt; | ||
23 | |||
24 | /* Start at MB1EA, since MB0EA will most likely be the ending address | ||
25 | for ROM space. */ | ||
26 | for(len = 0, i = CPC700_MB1EA; i <= CPC700_MB4EA; i+=4) { | ||
27 | amt = cpc700_read_memreg(i); | ||
28 | if (amt == 0) | ||
29 | break; | ||
30 | len = amt; | ||
31 | } | ||
32 | |||
33 | return len; | ||
34 | } | ||
35 | |||
36 | |||
diff --git a/arch/ppc/boot/simple/dummy.c b/arch/ppc/boot/simple/dummy.c new file mode 100644 index 000000000000..31dbf45bf99c --- /dev/null +++ b/arch/ppc/boot/simple/dummy.c | |||
@@ -0,0 +1,4 @@ | |||
1 | int main(void) | ||
2 | { | ||
3 | return 0; | ||
4 | } | ||
diff --git a/arch/ppc/boot/simple/embed_config.c b/arch/ppc/boot/simple/embed_config.c new file mode 100644 index 000000000000..c342b47e763e --- /dev/null +++ b/arch/ppc/boot/simple/embed_config.c | |||
@@ -0,0 +1,981 @@ | |||
1 | /* Board specific functions for those embedded 8xx boards that do | ||
2 | * not have boot monitor support for board information. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License as published by the | ||
6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
7 | * option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/types.h> | ||
11 | #include <linux/config.h> | ||
12 | #include <linux/string.h> | ||
13 | #include <asm/reg.h> | ||
14 | #ifdef CONFIG_8xx | ||
15 | #include <asm/mpc8xx.h> | ||
16 | #endif | ||
17 | #ifdef CONFIG_8260 | ||
18 | #include <asm/mpc8260.h> | ||
19 | #include <asm/immap_cpm2.h> | ||
20 | #endif | ||
21 | #ifdef CONFIG_40x | ||
22 | #include <asm/io.h> | ||
23 | #endif | ||
24 | extern unsigned long timebase_period_ns; | ||
25 | |||
26 | /* For those boards that don't provide one. | ||
27 | */ | ||
28 | #if !defined(CONFIG_MBX) | ||
29 | static bd_t bdinfo; | ||
30 | #endif | ||
31 | |||
32 | /* IIC functions. | ||
33 | * These are just the basic master read/write operations so we can | ||
34 | * examine serial EEPROM. | ||
35 | */ | ||
36 | extern void iic_read(uint devaddr, u_char *buf, uint offset, uint count); | ||
37 | |||
38 | /* Supply a default Ethernet address for those eval boards that don't | ||
39 | * ship with one. This is an address from the MBX board I have, so | ||
40 | * it is unlikely you will find it on your network. | ||
41 | */ | ||
42 | static ushort def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 }; | ||
43 | |||
44 | #if defined(CONFIG_MBX) | ||
45 | |||
46 | /* The MBX hands us a pretty much ready to go board descriptor. This | ||
47 | * is where the idea started in the first place. | ||
48 | */ | ||
49 | void | ||
50 | embed_config(bd_t **bdp) | ||
51 | { | ||
52 | u_char *mp; | ||
53 | u_char eebuf[128]; | ||
54 | int i = 8; | ||
55 | bd_t *bd; | ||
56 | |||
57 | bd = *bdp; | ||
58 | |||
59 | /* Read the first 128 bytes of the EEPROM. There is more, | ||
60 | * but this is all we need. | ||
61 | */ | ||
62 | iic_read(0xa4, eebuf, 0, 128); | ||
63 | |||
64 | /* All we are looking for is the Ethernet MAC address. The | ||
65 | * first 8 bytes are 'MOTOROLA', so check for part of that. | ||
66 | * Next, the VPD describes a MAC 'packet' as being of type 08 | ||
67 | * and size 06. So we look for that and the MAC must follow. | ||
68 | * If there are more than one, we still only care about the first. | ||
69 | * If it's there, assume we have a valid MAC address. If not, | ||
70 | * grab our default one. | ||
71 | */ | ||
72 | if ((*(uint *)eebuf) == 0x4d4f544f) { | ||
73 | while (i < 127 && !(eebuf[i] == 0x08 && eebuf[i + 1] == 0x06)) | ||
74 | i += eebuf[i + 1] + 2; /* skip this packet */ | ||
75 | |||
76 | if (i == 127) /* Couldn't find. */ | ||
77 | mp = (u_char *)def_enet_addr; | ||
78 | else | ||
79 | mp = &eebuf[i + 2]; | ||
80 | } | ||
81 | else | ||
82 | mp = (u_char *)def_enet_addr; | ||
83 | |||
84 | for (i=0; i<6; i++) | ||
85 | bd->bi_enetaddr[i] = *mp++; | ||
86 | |||
87 | /* The boot rom passes these to us in MHz. Linux now expects | ||
88 | * them to be in Hz. | ||
89 | */ | ||
90 | bd->bi_intfreq *= 1000000; | ||
91 | bd->bi_busfreq *= 1000000; | ||
92 | |||
93 | /* Stuff a baud rate here as well. | ||
94 | */ | ||
95 | bd->bi_baudrate = 9600; | ||
96 | } | ||
97 | #endif /* CONFIG_MBX */ | ||
98 | |||
99 | #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || \ | ||
100 | defined(CONFIG_RPX8260) || defined(CONFIG_EP405) | ||
101 | /* Helper functions for Embedded Planet boards. | ||
102 | */ | ||
103 | /* Because I didn't find anything that would do this....... | ||
104 | */ | ||
105 | u_char | ||
106 | aschex_to_byte(u_char *cp) | ||
107 | { | ||
108 | u_char byte, c; | ||
109 | |||
110 | c = *cp++; | ||
111 | |||
112 | if ((c >= 'A') && (c <= 'F')) { | ||
113 | c -= 'A'; | ||
114 | c += 10; | ||
115 | } else if ((c >= 'a') && (c <= 'f')) { | ||
116 | c -= 'a'; | ||
117 | c += 10; | ||
118 | } else | ||
119 | c -= '0'; | ||
120 | |||
121 | byte = c * 16; | ||
122 | |||
123 | c = *cp; | ||
124 | |||
125 | if ((c >= 'A') && (c <= 'F')) { | ||
126 | c -= 'A'; | ||
127 | c += 10; | ||
128 | } else if ((c >= 'a') && (c <= 'f')) { | ||
129 | c -= 'a'; | ||
130 | c += 10; | ||
131 | } else | ||
132 | c -= '0'; | ||
133 | |||
134 | byte += c; | ||
135 | |||
136 | return(byte); | ||
137 | } | ||
138 | |||
139 | static void | ||
140 | rpx_eth(bd_t *bd, u_char *cp) | ||
141 | { | ||
142 | int i; | ||
143 | |||
144 | for (i=0; i<6; i++) { | ||
145 | bd->bi_enetaddr[i] = aschex_to_byte(cp); | ||
146 | cp += 2; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | #ifdef CONFIG_RPX8260 | ||
151 | static uint | ||
152 | rpx_baseten(u_char *cp) | ||
153 | { | ||
154 | uint retval; | ||
155 | |||
156 | retval = 0; | ||
157 | |||
158 | while (*cp != '\n') { | ||
159 | retval *= 10; | ||
160 | retval += (*cp) - '0'; | ||
161 | cp++; | ||
162 | } | ||
163 | return(retval); | ||
164 | } | ||
165 | #endif | ||
166 | |||
167 | #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) | ||
168 | static void | ||
169 | rpx_brate(bd_t *bd, u_char *cp) | ||
170 | { | ||
171 | uint rate; | ||
172 | |||
173 | rate = 0; | ||
174 | |||
175 | while (*cp != '\n') { | ||
176 | rate *= 10; | ||
177 | rate += (*cp) - '0'; | ||
178 | cp++; | ||
179 | } | ||
180 | |||
181 | bd->bi_baudrate = rate * 100; | ||
182 | } | ||
183 | |||
184 | static void | ||
185 | rpx_cpuspeed(bd_t *bd, u_char *cp) | ||
186 | { | ||
187 | uint num, den; | ||
188 | |||
189 | num = den = 0; | ||
190 | |||
191 | while (*cp != '\n') { | ||
192 | num *= 10; | ||
193 | num += (*cp) - '0'; | ||
194 | cp++; | ||
195 | if (*cp == '/') { | ||
196 | cp++; | ||
197 | den = (*cp) - '0'; | ||
198 | break; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | /* I don't know why the RPX just can't state the actual | ||
203 | * CPU speed..... | ||
204 | */ | ||
205 | if (den) { | ||
206 | num /= den; | ||
207 | num *= den; | ||
208 | } | ||
209 | bd->bi_intfreq = bd->bi_busfreq = num * 1000000; | ||
210 | |||
211 | /* The 8xx can only run a maximum 50 MHz bus speed (until | ||
212 | * Motorola changes this :-). Greater than 50 MHz parts | ||
213 | * run internal/2 for bus speed. | ||
214 | */ | ||
215 | if (num > 50) | ||
216 | bd->bi_busfreq /= 2; | ||
217 | } | ||
218 | #endif | ||
219 | |||
220 | #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_EP405) | ||
221 | static void | ||
222 | rpx_memsize(bd_t *bd, u_char *cp) | ||
223 | { | ||
224 | uint size; | ||
225 | |||
226 | size = 0; | ||
227 | |||
228 | while (*cp != '\n') { | ||
229 | size *= 10; | ||
230 | size += (*cp) - '0'; | ||
231 | cp++; | ||
232 | } | ||
233 | |||
234 | bd->bi_memsize = size * 1024 * 1024; | ||
235 | } | ||
236 | #endif /* LITE || CLASSIC || EP405 */ | ||
237 | #if defined(CONFIG_EP405) | ||
238 | static void | ||
239 | rpx_nvramsize(bd_t *bd, u_char *cp) | ||
240 | { | ||
241 | uint size; | ||
242 | |||
243 | size = 0; | ||
244 | |||
245 | while (*cp != '\n') { | ||
246 | size *= 10; | ||
247 | size += (*cp) - '0'; | ||
248 | cp++; | ||
249 | } | ||
250 | |||
251 | bd->bi_nvramsize = size * 1024; | ||
252 | } | ||
253 | #endif /* CONFIG_EP405 */ | ||
254 | |||
255 | #endif /* Embedded Planet boards */ | ||
256 | |||
257 | #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) | ||
258 | |||
259 | /* Read the EEPROM on the RPX-Lite board. | ||
260 | */ | ||
261 | void | ||
262 | embed_config(bd_t **bdp) | ||
263 | { | ||
264 | u_char eebuf[256], *cp; | ||
265 | bd_t *bd; | ||
266 | |||
267 | /* Read the first 256 bytes of the EEPROM. I think this | ||
268 | * is really all there is, and I hope if it gets bigger the | ||
269 | * info we want is still up front. | ||
270 | */ | ||
271 | bd = &bdinfo; | ||
272 | *bdp = bd; | ||
273 | |||
274 | #if 1 | ||
275 | iic_read(0xa8, eebuf, 0, 128); | ||
276 | iic_read(0xa8, &eebuf[128], 128, 128); | ||
277 | |||
278 | /* We look for two things, the Ethernet address and the | ||
279 | * serial baud rate. The records are separated by | ||
280 | * newlines. | ||
281 | */ | ||
282 | cp = eebuf; | ||
283 | for (;;) { | ||
284 | if (*cp == 'E') { | ||
285 | cp++; | ||
286 | if (*cp == 'A') { | ||
287 | cp += 2; | ||
288 | rpx_eth(bd, cp); | ||
289 | } | ||
290 | } | ||
291 | if (*cp == 'S') { | ||
292 | cp++; | ||
293 | if (*cp == 'B') { | ||
294 | cp += 2; | ||
295 | rpx_brate(bd, cp); | ||
296 | } | ||
297 | } | ||
298 | if (*cp == 'D') { | ||
299 | cp++; | ||
300 | if (*cp == '1') { | ||
301 | cp += 2; | ||
302 | rpx_memsize(bd, cp); | ||
303 | } | ||
304 | } | ||
305 | if (*cp == 'H') { | ||
306 | cp++; | ||
307 | if (*cp == 'Z') { | ||
308 | cp += 2; | ||
309 | rpx_cpuspeed(bd, cp); | ||
310 | } | ||
311 | } | ||
312 | |||
313 | /* Scan to the end of the record. | ||
314 | */ | ||
315 | while ((*cp != '\n') && (*cp != 0xff)) | ||
316 | cp++; | ||
317 | |||
318 | /* If the next character is a 0 or ff, we are done. | ||
319 | */ | ||
320 | cp++; | ||
321 | if ((*cp == 0) || (*cp == 0xff)) | ||
322 | break; | ||
323 | } | ||
324 | bd->bi_memstart = 0; | ||
325 | #else | ||
326 | /* For boards without initialized EEPROM. | ||
327 | */ | ||
328 | bd->bi_memstart = 0; | ||
329 | bd->bi_memsize = (8 * 1024 * 1024); | ||
330 | bd->bi_intfreq = 48000000; | ||
331 | bd->bi_busfreq = 48000000; | ||
332 | bd->bi_baudrate = 9600; | ||
333 | #endif | ||
334 | } | ||
335 | #endif /* RPXLITE || RPXCLASSIC */ | ||
336 | |||
337 | #ifdef CONFIG_BSEIP | ||
338 | /* Build a board information structure for the BSE ip-Engine. | ||
339 | * There is more to come since we will add some environment | ||
340 | * variables and a function to read them. | ||
341 | */ | ||
342 | void | ||
343 | embed_config(bd_t **bdp) | ||
344 | { | ||
345 | u_char *cp; | ||
346 | int i; | ||
347 | bd_t *bd; | ||
348 | |||
349 | bd = &bdinfo; | ||
350 | *bdp = bd; | ||
351 | |||
352 | /* Baud rate and processor speed will eventually come | ||
353 | * from the environment variables. | ||
354 | */ | ||
355 | bd->bi_baudrate = 9600; | ||
356 | |||
357 | /* Get the Ethernet station address from the Flash ROM. | ||
358 | */ | ||
359 | cp = (u_char *)0xfe003ffa; | ||
360 | for (i=0; i<6; i++) { | ||
361 | bd->bi_enetaddr[i] = *cp++; | ||
362 | } | ||
363 | |||
364 | /* The rest of this should come from the environment as well. | ||
365 | */ | ||
366 | bd->bi_memstart = 0; | ||
367 | bd->bi_memsize = (16 * 1024 * 1024); | ||
368 | bd->bi_intfreq = 48000000; | ||
369 | bd->bi_busfreq = 48000000; | ||
370 | } | ||
371 | #endif /* BSEIP */ | ||
372 | |||
373 | #ifdef CONFIG_FADS | ||
374 | /* Build a board information structure for the FADS. | ||
375 | */ | ||
376 | void | ||
377 | embed_config(bd_t **bdp) | ||
378 | { | ||
379 | u_char *cp; | ||
380 | int i; | ||
381 | bd_t *bd; | ||
382 | |||
383 | bd = &bdinfo; | ||
384 | *bdp = bd; | ||
385 | |||
386 | /* Just fill in some known values. | ||
387 | */ | ||
388 | bd->bi_baudrate = 9600; | ||
389 | |||
390 | /* Use default enet. | ||
391 | */ | ||
392 | cp = (u_char *)def_enet_addr; | ||
393 | for (i=0; i<6; i++) { | ||
394 | bd->bi_enetaddr[i] = *cp++; | ||
395 | } | ||
396 | |||
397 | bd->bi_memstart = 0; | ||
398 | bd->bi_memsize = (8 * 1024 * 1024); | ||
399 | bd->bi_intfreq = 40000000; | ||
400 | bd->bi_busfreq = 40000000; | ||
401 | } | ||
402 | #endif /* FADS */ | ||
403 | |||
404 | #ifdef CONFIG_8260 | ||
405 | /* Compute 8260 clock values if the rom doesn't provide them. | ||
406 | */ | ||
407 | static unsigned char bus2core_8260[] = { | ||
408 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | ||
409 | 3, 2, 2, 2, 4, 4, 5, 9, 6, 11, 8, 10, 3, 12, 7, 2, | ||
410 | 6, 5, 13, 2, 14, 4, 15, 2, 3, 11, 8, 10, 16, 12, 7, 2, | ||
411 | }; | ||
412 | |||
413 | static void | ||
414 | clk_8260(bd_t *bd) | ||
415 | { | ||
416 | uint scmr, vco_out, clkin; | ||
417 | uint plldf, pllmf, corecnf; | ||
418 | volatile cpm2_map_t *ip; | ||
419 | |||
420 | ip = (cpm2_map_t *)CPM_MAP_ADDR; | ||
421 | scmr = ip->im_clkrst.car_scmr; | ||
422 | |||
423 | /* The clkin is always bus frequency. | ||
424 | */ | ||
425 | clkin = bd->bi_busfreq; | ||
426 | |||
427 | /* Collect the bits from the scmr. | ||
428 | */ | ||
429 | plldf = (scmr >> 12) & 1; | ||
430 | pllmf = scmr & 0xfff; | ||
431 | corecnf = (scmr >> 24) &0x1f; | ||
432 | |||
433 | /* This is arithmetic from the 8260 manual. | ||
434 | */ | ||
435 | vco_out = clkin / (plldf + 1); | ||
436 | vco_out *= 2 * (pllmf + 1); | ||
437 | bd->bi_vco = vco_out; /* Save for later */ | ||
438 | |||
439 | bd->bi_cpmfreq = vco_out / 2; /* CPM Freq, in MHz */ | ||
440 | bd->bi_intfreq = bd->bi_busfreq * bus2core_8260[corecnf] / 2; | ||
441 | |||
442 | /* Set Baud rate divisor. The power up default is divide by 16, | ||
443 | * but we set it again here in case it was changed. | ||
444 | */ | ||
445 | ip->im_clkrst.car_sccr = 1; /* DIV 16 BRG */ | ||
446 | bd->bi_brgfreq = vco_out / 16; | ||
447 | } | ||
448 | |||
449 | static unsigned char bus2core_8280[] = { | ||
450 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | ||
451 | 3, 2, 2, 2, 4, 4, 5, 9, 6, 11, 8, 10, 3, 12, 7, 2, | ||
452 | 6, 5, 13, 2, 14, 2, 15, 2, 3, 2, 2, 2, 16, 2, 2, 2, | ||
453 | }; | ||
454 | |||
455 | static void | ||
456 | clk_8280(bd_t *bd) | ||
457 | { | ||
458 | uint scmr, main_clk, clkin; | ||
459 | uint pllmf, corecnf; | ||
460 | volatile cpm2_map_t *ip; | ||
461 | |||
462 | ip = (cpm2_map_t *)CPM_MAP_ADDR; | ||
463 | scmr = ip->im_clkrst.car_scmr; | ||
464 | |||
465 | /* The clkin is always bus frequency. | ||
466 | */ | ||
467 | clkin = bd->bi_busfreq; | ||
468 | |||
469 | /* Collect the bits from the scmr. | ||
470 | */ | ||
471 | pllmf = scmr & 0xf; | ||
472 | corecnf = (scmr >> 24) & 0x1f; | ||
473 | |||
474 | /* This is arithmetic from the 8280 manual. | ||
475 | */ | ||
476 | main_clk = clkin * (pllmf + 1); | ||
477 | |||
478 | bd->bi_cpmfreq = main_clk / 2; /* CPM Freq, in MHz */ | ||
479 | bd->bi_intfreq = bd->bi_busfreq * bus2core_8280[corecnf] / 2; | ||
480 | |||
481 | /* Set Baud rate divisor. The power up default is divide by 16, | ||
482 | * but we set it again here in case it was changed. | ||
483 | */ | ||
484 | ip->im_clkrst.car_sccr = (ip->im_clkrst.car_sccr & 0x3) | 0x1; | ||
485 | bd->bi_brgfreq = main_clk / 16; | ||
486 | } | ||
487 | #endif | ||
488 | |||
489 | #ifdef CONFIG_SBC82xx | ||
490 | void | ||
491 | embed_config(bd_t **bdp) | ||
492 | { | ||
493 | u_char *cp; | ||
494 | int i; | ||
495 | bd_t *bd; | ||
496 | unsigned long pvr; | ||
497 | |||
498 | bd = *bdp; | ||
499 | |||
500 | bd = &bdinfo; | ||
501 | *bdp = bd; | ||
502 | bd->bi_baudrate = 9600; | ||
503 | bd->bi_memsize = 256 * 1024 * 1024; /* just a guess */ | ||
504 | |||
505 | cp = (void*)SBC82xx_MACADDR_NVRAM_SCC1; | ||
506 | memcpy(bd->bi_enetaddr, cp, 6); | ||
507 | |||
508 | /* can busfreq be calculated? */ | ||
509 | pvr = mfspr(SPRN_PVR); | ||
510 | if ((pvr & 0xffff0000) == 0x80820000) { | ||
511 | bd->bi_busfreq = 100000000; | ||
512 | clk_8280(bd); | ||
513 | } else { | ||
514 | bd->bi_busfreq = 66000000; | ||
515 | clk_8260(bd); | ||
516 | } | ||
517 | |||
518 | } | ||
519 | #endif /* SBC82xx */ | ||
520 | |||
521 | #if defined(CONFIG_EST8260) || defined(CONFIG_TQM8260) | ||
522 | void | ||
523 | embed_config(bd_t **bdp) | ||
524 | { | ||
525 | u_char *cp; | ||
526 | int i; | ||
527 | bd_t *bd; | ||
528 | |||
529 | bd = *bdp; | ||
530 | #if 0 | ||
531 | /* This is actually provided by my boot rom. I have it | ||
532 | * here for those people that may load the kernel with | ||
533 | * a JTAG/COP tool and not the rom monitor. | ||
534 | */ | ||
535 | bd->bi_baudrate = 115200; | ||
536 | bd->bi_intfreq = 200000000; | ||
537 | bd->bi_busfreq = 66666666; | ||
538 | bd->bi_cpmfreq = 66666666; | ||
539 | bd->bi_brgfreq = 33333333; | ||
540 | bd->bi_memsize = 16 * 1024 * 1024; | ||
541 | #else | ||
542 | /* The boot rom passes these to us in MHz. Linux now expects | ||
543 | * them to be in Hz. | ||
544 | */ | ||
545 | bd->bi_intfreq *= 1000000; | ||
546 | bd->bi_busfreq *= 1000000; | ||
547 | bd->bi_cpmfreq *= 1000000; | ||
548 | bd->bi_brgfreq *= 1000000; | ||
549 | #endif | ||
550 | |||
551 | cp = (u_char *)def_enet_addr; | ||
552 | for (i=0; i<6; i++) { | ||
553 | bd->bi_enetaddr[i] = *cp++; | ||
554 | } | ||
555 | } | ||
556 | #endif /* EST8260 */ | ||
557 | |||
558 | #ifdef CONFIG_SBS8260 | ||
559 | void | ||
560 | embed_config(bd_t **bdp) | ||
561 | { | ||
562 | u_char *cp; | ||
563 | int i; | ||
564 | bd_t *bd; | ||
565 | |||
566 | /* This should provided by the boot rom. | ||
567 | */ | ||
568 | bd = &bdinfo; | ||
569 | *bdp = bd; | ||
570 | bd->bi_baudrate = 9600; | ||
571 | bd->bi_memsize = 64 * 1024 * 1024; | ||
572 | |||
573 | /* Set all of the clocks. We have to know the speed of the | ||
574 | * external clock. The development board had 66 MHz. | ||
575 | */ | ||
576 | bd->bi_busfreq = 66666666; | ||
577 | clk_8260(bd); | ||
578 | |||
579 | /* I don't know how to compute this yet. | ||
580 | */ | ||
581 | bd->bi_intfreq = 133000000; | ||
582 | |||
583 | |||
584 | cp = (u_char *)def_enet_addr; | ||
585 | for (i=0; i<6; i++) { | ||
586 | bd->bi_enetaddr[i] = *cp++; | ||
587 | } | ||
588 | } | ||
589 | #endif /* SBS8260 */ | ||
590 | |||
591 | #ifdef CONFIG_RPX8260 | ||
592 | void | ||
593 | embed_config(bd_t **bdp) | ||
594 | { | ||
595 | u_char *cp, *keyvals; | ||
596 | int i; | ||
597 | bd_t *bd; | ||
598 | |||
599 | keyvals = (u_char *)*bdp; | ||
600 | |||
601 | bd = &bdinfo; | ||
602 | *bdp = bd; | ||
603 | |||
604 | /* This is almost identical to the RPX-Lite/Classic functions | ||
605 | * on the 8xx boards. It would be nice to have a key lookup | ||
606 | * function in a string, but the format of all of the fields | ||
607 | * is slightly different. | ||
608 | */ | ||
609 | cp = keyvals; | ||
610 | for (;;) { | ||
611 | if (*cp == 'E') { | ||
612 | cp++; | ||
613 | if (*cp == 'A') { | ||
614 | cp += 2; | ||
615 | rpx_eth(bd, cp); | ||
616 | } | ||
617 | } | ||
618 | if (*cp == 'S') { | ||
619 | cp++; | ||
620 | if (*cp == 'B') { | ||
621 | cp += 2; | ||
622 | bd->bi_baudrate = rpx_baseten(cp); | ||
623 | } | ||
624 | } | ||
625 | if (*cp == 'D') { | ||
626 | cp++; | ||
627 | if (*cp == '1') { | ||
628 | cp += 2; | ||
629 | bd->bi_memsize = rpx_baseten(cp) * 1024 * 1024; | ||
630 | } | ||
631 | } | ||
632 | if (*cp == 'X') { | ||
633 | cp++; | ||
634 | if (*cp == 'T') { | ||
635 | cp += 2; | ||
636 | bd->bi_busfreq = rpx_baseten(cp); | ||
637 | } | ||
638 | } | ||
639 | if (*cp == 'N') { | ||
640 | cp++; | ||
641 | if (*cp == 'V') { | ||
642 | cp += 2; | ||
643 | bd->bi_nvsize = rpx_baseten(cp) * 1024 * 1024; | ||
644 | } | ||
645 | } | ||
646 | |||
647 | /* Scan to the end of the record. | ||
648 | */ | ||
649 | while ((*cp != '\n') && (*cp != 0xff)) | ||
650 | cp++; | ||
651 | |||
652 | /* If the next character is a 0 or ff, we are done. | ||
653 | */ | ||
654 | cp++; | ||
655 | if ((*cp == 0) || (*cp == 0xff)) | ||
656 | break; | ||
657 | } | ||
658 | bd->bi_memstart = 0; | ||
659 | |||
660 | /* The memory size includes both the 60x and local bus DRAM. | ||
661 | * I don't want to use the local bus DRAM for real memory, | ||
662 | * so subtract it out. It would be nice if they were separate | ||
663 | * keys. | ||
664 | */ | ||
665 | bd->bi_memsize -= 32 * 1024 * 1024; | ||
666 | |||
667 | /* Set all of the clocks. We have to know the speed of the | ||
668 | * external clock. | ||
669 | */ | ||
670 | clk_8260(bd); | ||
671 | |||
672 | /* I don't know how to compute this yet. | ||
673 | */ | ||
674 | bd->bi_intfreq = 200000000; | ||
675 | } | ||
676 | #endif /* RPX6 for testing */ | ||
677 | |||
678 | #ifdef CONFIG_ADS8260 | ||
679 | void | ||
680 | embed_config(bd_t **bdp) | ||
681 | { | ||
682 | u_char *cp; | ||
683 | int i; | ||
684 | bd_t *bd; | ||
685 | |||
686 | /* This should provided by the boot rom. | ||
687 | */ | ||
688 | bd = &bdinfo; | ||
689 | *bdp = bd; | ||
690 | bd->bi_baudrate = 9600; | ||
691 | bd->bi_memsize = 16 * 1024 * 1024; | ||
692 | |||
693 | /* Set all of the clocks. We have to know the speed of the | ||
694 | * external clock. The development board had 66 MHz. | ||
695 | */ | ||
696 | bd->bi_busfreq = 66666666; | ||
697 | clk_8260(bd); | ||
698 | |||
699 | /* I don't know how to compute this yet. | ||
700 | */ | ||
701 | bd->bi_intfreq = 200000000; | ||
702 | |||
703 | |||
704 | cp = (u_char *)def_enet_addr; | ||
705 | for (i=0; i<6; i++) { | ||
706 | bd->bi_enetaddr[i] = *cp++; | ||
707 | } | ||
708 | } | ||
709 | #endif /* ADS8260 */ | ||
710 | |||
711 | #ifdef CONFIG_WILLOW | ||
712 | void | ||
713 | embed_config(bd_t **bdp) | ||
714 | { | ||
715 | u_char *cp; | ||
716 | int i; | ||
717 | bd_t *bd; | ||
718 | |||
719 | /* Willow has Open Firmware....I should learn how to get this | ||
720 | * information from it. | ||
721 | */ | ||
722 | bd = &bdinfo; | ||
723 | *bdp = bd; | ||
724 | bd->bi_baudrate = 9600; | ||
725 | bd->bi_memsize = 32 * 1024 * 1024; | ||
726 | |||
727 | /* Set all of the clocks. We have to know the speed of the | ||
728 | * external clock. The development board had 66 MHz. | ||
729 | */ | ||
730 | bd->bi_busfreq = 66666666; | ||
731 | clk_8260(bd); | ||
732 | |||
733 | /* I don't know how to compute this yet. | ||
734 | */ | ||
735 | bd->bi_intfreq = 200000000; | ||
736 | |||
737 | |||
738 | cp = (u_char *)def_enet_addr; | ||
739 | for (i=0; i<6; i++) { | ||
740 | bd->bi_enetaddr[i] = *cp++; | ||
741 | } | ||
742 | } | ||
743 | #endif /* WILLOW */ | ||
744 | |||
745 | #ifdef CONFIG_XILINX_ML300 | ||
746 | void | ||
747 | embed_config(bd_t ** bdp) | ||
748 | { | ||
749 | static const unsigned long line_size = 32; | ||
750 | static const unsigned long congruence_classes = 256; | ||
751 | unsigned long addr; | ||
752 | unsigned long dccr; | ||
753 | bd_t *bd; | ||
754 | |||
755 | /* | ||
756 | * Invalidate the data cache if the data cache is turned off. | ||
757 | * - The 405 core does not invalidate the data cache on power-up | ||
758 | * or reset but does turn off the data cache. We cannot assume | ||
759 | * that the cache contents are valid. | ||
760 | * - If the data cache is turned on this must have been done by | ||
761 | * a bootloader and we assume that the cache contents are | ||
762 | * valid. | ||
763 | */ | ||
764 | __asm__("mfdccr %0": "=r" (dccr)); | ||
765 | if (dccr == 0) { | ||
766 | for (addr = 0; | ||
767 | addr < (congruence_classes * line_size); | ||
768 | addr += line_size) { | ||
769 | __asm__("dccci 0,%0": :"b"(addr)); | ||
770 | } | ||
771 | } | ||
772 | |||
773 | bd = &bdinfo; | ||
774 | *bdp = bd; | ||
775 | bd->bi_memsize = XPAR_DDR_0_SIZE; | ||
776 | bd->bi_intfreq = XPAR_CORE_CLOCK_FREQ_HZ; | ||
777 | bd->bi_busfreq = XPAR_PLB_CLOCK_FREQ_HZ; | ||
778 | bd->bi_pci_busfreq = XPAR_PCI_0_CLOCK_FREQ_HZ; | ||
779 | timebase_period_ns = 1000000000 / bd->bi_tbfreq; | ||
780 | /* see bi_tbfreq definition in arch/ppc/platforms/4xx/xilinx_ml300.h */ | ||
781 | } | ||
782 | #endif /* CONFIG_XILINX_ML300 */ | ||
783 | |||
784 | #ifdef CONFIG_IBM_OPENBIOS | ||
785 | /* This could possibly work for all treeboot roms. | ||
786 | */ | ||
787 | #if defined(CONFIG_ASH) || defined(CONFIG_BEECH) || defined(CONFIG_BUBINGA) | ||
788 | #define BOARD_INFO_VECTOR 0xFFF80B50 /* openbios 1.19 moved this vector down - armin */ | ||
789 | #else | ||
790 | #define BOARD_INFO_VECTOR 0xFFFE0B50 | ||
791 | #endif | ||
792 | |||
793 | #ifdef CONFIG_BEECH | ||
794 | static void | ||
795 | get_board_info(bd_t **bdp) | ||
796 | { | ||
797 | typedef void (*PFV)(bd_t *bd); | ||
798 | ((PFV)(*(unsigned long *)BOARD_INFO_VECTOR))(*bdp); | ||
799 | return; | ||
800 | } | ||
801 | |||
802 | void | ||
803 | embed_config(bd_t **bdp) | ||
804 | { | ||
805 | *bdp = &bdinfo; | ||
806 | get_board_info(bdp); | ||
807 | } | ||
808 | #else /* !CONFIG_BEECH */ | ||
809 | void | ||
810 | embed_config(bd_t **bdp) | ||
811 | { | ||
812 | u_char *cp; | ||
813 | int i; | ||
814 | bd_t *bd, *treeboot_bd; | ||
815 | bd_t *(*get_board_info)(void) = | ||
816 | (bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR); | ||
817 | #if !defined(CONFIG_STB03xxx) | ||
818 | |||
819 | /* shut down the Ethernet controller that the boot rom | ||
820 | * sometimes leaves running. | ||
821 | */ | ||
822 | mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); /* 1st reset MAL */ | ||
823 | while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for the reset */ | ||
824 | out_be32((volatile u32*)EMAC0_BASE,0x20000000); /* then reset EMAC */ | ||
825 | #endif | ||
826 | |||
827 | bd = &bdinfo; | ||
828 | *bdp = bd; | ||
829 | if ((treeboot_bd = get_board_info()) != NULL) { | ||
830 | memcpy(bd, treeboot_bd, sizeof(bd_t)); | ||
831 | } | ||
832 | else { | ||
833 | /* Hmmm...better try to stuff some defaults. | ||
834 | */ | ||
835 | bd->bi_memsize = 16 * 1024 * 1024; | ||
836 | cp = (u_char *)def_enet_addr; | ||
837 | for (i=0; i<6; i++) { | ||
838 | /* I should probably put different ones here, | ||
839 | * hopefully only one is used. | ||
840 | */ | ||
841 | bd->BD_EMAC_ADDR(0,i) = *cp; | ||
842 | |||
843 | #ifdef CONFIG_PCI | ||
844 | bd->bi_pci_enetaddr[i] = *cp++; | ||
845 | #endif | ||
846 | } | ||
847 | bd->bi_tbfreq = 200 * 1000 * 1000; | ||
848 | bd->bi_intfreq = 200000000; | ||
849 | bd->bi_busfreq = 100000000; | ||
850 | #ifdef CONFIG_PCI | ||
851 | bd->bi_pci_busfreq = 66666666; | ||
852 | #endif | ||
853 | } | ||
854 | /* Yeah, this look weird, but on Redwood 4 they are | ||
855 | * different object in the structure. Sincr Redwwood 5 | ||
856 | * and Redwood 6 use OpenBIOS, it requires a special value. | ||
857 | */ | ||
858 | #if defined(CONFIG_REDWOOD_5) || defined (CONFIG_REDWOOD_6) | ||
859 | bd->bi_tbfreq = 27 * 1000 * 1000; | ||
860 | #endif | ||
861 | timebase_period_ns = 1000000000 / bd->bi_tbfreq; | ||
862 | } | ||
863 | #endif /* CONFIG_BEECH */ | ||
864 | #endif /* CONFIG_IBM_OPENBIOS */ | ||
865 | |||
866 | #ifdef CONFIG_EP405 | ||
867 | #include <linux/serial_reg.h> | ||
868 | |||
869 | void | ||
870 | embed_config(bd_t **bdp) | ||
871 | { | ||
872 | u32 chcr0; | ||
873 | u_char *cp; | ||
874 | bd_t *bd; | ||
875 | |||
876 | /* Different versions of the PlanetCore firmware vary in how | ||
877 | they set up the serial port - in particular whether they | ||
878 | use the internal or external serial clock for UART0. Make | ||
879 | sure the UART is in a known state. */ | ||
880 | /* FIXME: We should use the board's 11.0592MHz external serial | ||
881 | clock - it will be more accurate for serial rates. For | ||
882 | now, however the baud rates in ep405.h are for the internal | ||
883 | clock. */ | ||
884 | chcr0 = mfdcr(DCRN_CHCR0); | ||
885 | if ( (chcr0 & 0x1fff) != 0x103e ) { | ||
886 | mtdcr(DCRN_CHCR0, (chcr0 & 0xffffe000) | 0x103e); | ||
887 | /* The following tricks serial_init() into resetting the baud rate */ | ||
888 | writeb(0, UART0_IO_BASE + UART_LCR); | ||
889 | } | ||
890 | |||
891 | /* We haven't seen actual problems with the EP405 leaving the | ||
892 | * EMAC running (as we have on Walnut). But the registers | ||
893 | * suggest it may not be left completely quiescent. Reset it | ||
894 | * just to be sure. */ | ||
895 | mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); /* 1st reset MAL */ | ||
896 | while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for the reset */ | ||
897 | out_be32((unsigned *)EMAC0_BASE,0x20000000); /* then reset EMAC */ | ||
898 | |||
899 | bd = &bdinfo; | ||
900 | *bdp = bd; | ||
901 | #if 1 | ||
902 | cp = (u_char *)0xF0000EE0; | ||
903 | for (;;) { | ||
904 | if (*cp == 'E') { | ||
905 | cp++; | ||
906 | if (*cp == 'A') { | ||
907 | cp += 2; | ||
908 | rpx_eth(bd, cp); | ||
909 | } | ||
910 | } | ||
911 | |||
912 | if (*cp == 'D') { | ||
913 | cp++; | ||
914 | if (*cp == '1') { | ||
915 | cp += 2; | ||
916 | rpx_memsize(bd, cp); | ||
917 | } | ||
918 | } | ||
919 | |||
920 | if (*cp == 'N') { | ||
921 | cp++; | ||
922 | if (*cp == 'V') { | ||
923 | cp += 2; | ||
924 | rpx_nvramsize(bd, cp); | ||
925 | } | ||
926 | } | ||
927 | while ((*cp != '\n') && (*cp != 0xff)) | ||
928 | cp++; | ||
929 | |||
930 | cp++; | ||
931 | if ((*cp == 0) || (*cp == 0xff)) | ||
932 | break; | ||
933 | } | ||
934 | bd->bi_intfreq = 200000000; | ||
935 | bd->bi_busfreq = 100000000; | ||
936 | bd->bi_pci_busfreq= 33000000 ; | ||
937 | #else | ||
938 | |||
939 | bd->bi_memsize = 64000000; | ||
940 | bd->bi_intfreq = 200000000; | ||
941 | bd->bi_busfreq = 100000000; | ||
942 | bd->bi_pci_busfreq= 33000000 ; | ||
943 | #endif | ||
944 | } | ||
945 | #endif | ||
946 | |||
947 | #ifdef CONFIG_RAINIER | ||
948 | /* Rainier uses vxworks bootrom */ | ||
949 | void | ||
950 | embed_config(bd_t **bdp) | ||
951 | { | ||
952 | u_char *cp; | ||
953 | int i; | ||
954 | bd_t *bd; | ||
955 | |||
956 | bd = &bdinfo; | ||
957 | *bdp = bd; | ||
958 | |||
959 | for(i=0;i<8192;i+=32) { | ||
960 | __asm__("dccci 0,%0" :: "r" (i)); | ||
961 | } | ||
962 | __asm__("iccci 0,0"); | ||
963 | __asm__("sync;isync"); | ||
964 | |||
965 | /* init ram for parity */ | ||
966 | memset(0, 0,0x400000); /* Lo memory */ | ||
967 | |||
968 | |||
969 | bd->bi_memsize = (32 * 1024 * 1024) ; | ||
970 | bd->bi_intfreq = 133000000; //the internal clock is 133 MHz | ||
971 | bd->bi_busfreq = 100000000; | ||
972 | bd->bi_pci_busfreq= 33000000; | ||
973 | |||
974 | cp = (u_char *)def_enet_addr; | ||
975 | for (i=0; i<6; i++) { | ||
976 | bd->bi_enetaddr[i] = *cp++; | ||
977 | } | ||
978 | |||
979 | } | ||
980 | #endif | ||
981 | |||
diff --git a/arch/ppc/boot/simple/head.S b/arch/ppc/boot/simple/head.S new file mode 100644 index 000000000000..524053202bb4 --- /dev/null +++ b/arch/ppc/boot/simple/head.S | |||
@@ -0,0 +1,142 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/head.S | ||
3 | * | ||
4 | * Initial board bringup code for many different boards. | ||
5 | * | ||
6 | * Author: Tom Rini | ||
7 | * trini@mvista.com | ||
8 | * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others). | ||
9 | * | ||
10 | * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under | ||
11 | * the terms of the GNU General Public License version 2. This program | ||
12 | * is licensed "as is" without any warranty of any kind, whether express | ||
13 | * or implied. | ||
14 | */ | ||
15 | |||
16 | #include <linux/config.h> | ||
17 | #include <asm/reg.h> | ||
18 | #include <asm/cache.h> | ||
19 | #include <asm/ppc_asm.h> | ||
20 | |||
21 | .text | ||
22 | |||
23 | /* | ||
24 | * Begin at some arbitrary location in RAM or Flash | ||
25 | * Initialize core registers | ||
26 | * Configure memory controller (Not executing from RAM) | ||
27 | * Move the boot code to the link address (8M) | ||
28 | * Setup C stack | ||
29 | * Initialize UART | ||
30 | * Decompress the kernel to 0x0 | ||
31 | * Jump to the kernel entry | ||
32 | * | ||
33 | */ | ||
34 | |||
35 | .globl start | ||
36 | start: | ||
37 | bl start_ | ||
38 | #ifdef CONFIG_IBM_OPENBIOS | ||
39 | /* The IBM "Tree" bootrom knows that the address of the bootrom | ||
40 | * read only structure is 4 bytes after _start. | ||
41 | */ | ||
42 | .long 0x62726f6d # structure ID - "brom" | ||
43 | .long 0x5f726f00 # - "_ro\0" | ||
44 | .long 1 # structure version | ||
45 | .long bootrom_cmdline # address of *bootrom_cmdline | ||
46 | #endif | ||
47 | |||
48 | start_: | ||
49 | #ifdef CONFIG_FORCE | ||
50 | /* We have some really bad firmware. We must disable the L1 | ||
51 | * icache/dcache now or the board won't boot. | ||
52 | */ | ||
53 | li r4,0x0000 | ||
54 | isync | ||
55 | mtspr SPRN_HID0,r4 | ||
56 | sync | ||
57 | isync | ||
58 | #endif | ||
59 | |||
60 | #if defined(CONFIG_MBX) || defined(CONFIG_RPX8260) || defined(CONFIG_PPC_PREP) | ||
61 | mr r29,r3 /* On the MBX860, r3 is the board info pointer. | ||
62 | * On the RPXSUPER, r3 points to the NVRAM | ||
63 | * configuration keys. | ||
64 | * On PReP, r3 is the pointer to the residual data. | ||
65 | */ | ||
66 | #endif | ||
67 | |||
68 | mflr r3 /* Save our actual starting address. */ | ||
69 | |||
70 | /* The following functions we call must not modify r3 or r4..... | ||
71 | */ | ||
72 | #ifdef CONFIG_6xx | ||
73 | /* On PReP we must look at the OpenFirmware pointer and sanity | ||
74 | * test it. On other platforms, we disable the MMU right now | ||
75 | * and other bits. | ||
76 | */ | ||
77 | #ifdef CONFIG_PPC_PREP | ||
78 | /* | ||
79 | * Save the OF pointer to r25, but only if the entry point is in a sane | ||
80 | * location; if not we store 0. If there is no entry point, or it is | ||
81 | * invalid, we establish the default MSR value immediately. Otherwise, | ||
82 | * we defer doing that, to allow OF functions to be called, until we | ||
83 | * begin uncompressing the kernel. | ||
84 | */ | ||
85 | lis r8,0x0fff /* r8 = 0x0fffffff */ | ||
86 | ori r8,r8,0xffff | ||
87 | |||
88 | subc r8,r8,r5 /* r8 = (r5 <= r8) ? ~0 : 0 */ | ||
89 | subfe r8,r8,r8 | ||
90 | nand r8,r8,r8 | ||
91 | |||
92 | and. r5,r5,r8 /* r5 will be cleared if (r5 > r8) */ | ||
93 | bne+ haveOF | ||
94 | |||
95 | li r8,MSR_IP|MSR_FP /* Not OF: set MSR immediately */ | ||
96 | mtmsr r8 | ||
97 | isync | ||
98 | haveOF: | ||
99 | mr r25,r5 | ||
100 | #else | ||
101 | bl disable_6xx_mmu | ||
102 | #endif | ||
103 | bl disable_6xx_l1cache | ||
104 | |||
105 | CLEAR_CACHES | ||
106 | #endif | ||
107 | |||
108 | #ifdef CONFIG_8xx | ||
109 | mfmsr r8 /* Turn off interrupts */ | ||
110 | li r9,0 | ||
111 | ori r9,r9,MSR_EE | ||
112 | andc r8,r8,r9 | ||
113 | mtmsr r8 | ||
114 | |||
115 | /* We do this because some boot roms don't initialize the | ||
116 | * processor correctly. Don't do this if you want to debug | ||
117 | * using a BDM device. | ||
118 | */ | ||
119 | li r4,0 /* Zero DER to prevent FRZ */ | ||
120 | mtspr SPRN_DER,r4 | ||
121 | #endif | ||
122 | |||
123 | #ifdef CONFIG_REDWOOD_4 | ||
124 | /* All of this Redwood 4 stuff will soon disappear when the | ||
125 | * boot rom is straightened out. | ||
126 | */ | ||
127 | mr r29, r3 /* Easier than changing the other code */ | ||
128 | bl HdwInit | ||
129 | mr r3, r29 | ||
130 | #endif | ||
131 | |||
132 | #if defined(CONFIG_MBX) || defined(CONFIG_RPX8260) || defined(CONFIG_PPC_PREP) | ||
133 | mr r4,r29 /* put the board info pointer where the relocate | ||
134 | * routine will find it | ||
135 | */ | ||
136 | #endif | ||
137 | |||
138 | /* Get the load address. | ||
139 | */ | ||
140 | subi r3, r3, 4 /* Get the actual IP, not NIP */ | ||
141 | b relocate | ||
142 | |||
diff --git a/arch/ppc/boot/simple/iic.c b/arch/ppc/boot/simple/iic.c new file mode 100644 index 000000000000..e4efd838bfaa --- /dev/null +++ b/arch/ppc/boot/simple/iic.c | |||
@@ -0,0 +1,214 @@ | |||
1 | /* Minimal support functions to read configuration from IIC EEPROMS | ||
2 | * on MPC8xx boards. Originally written for RPGC RPX-Lite. | ||
3 | * Dan Malek (dmalek@jlc.net). | ||
4 | */ | ||
5 | #include <linux/types.h> | ||
6 | #include <asm/uaccess.h> | ||
7 | #include <asm/mpc8xx.h> | ||
8 | #include <asm/commproc.h> | ||
9 | |||
10 | |||
11 | /* IIC functions. | ||
12 | * These are just the basic master read/write operations so we can | ||
13 | * examine serial EEPROM. | ||
14 | */ | ||
15 | void iic_read(uint devaddr, u_char *buf, uint offset, uint count); | ||
16 | |||
17 | static int iic_init_done; | ||
18 | |||
19 | static void | ||
20 | iic_init(void) | ||
21 | { | ||
22 | volatile iic_t *iip; | ||
23 | volatile i2c8xx_t *i2c; | ||
24 | volatile cpm8xx_t *cp; | ||
25 | volatile immap_t *immap; | ||
26 | uint dpaddr; | ||
27 | |||
28 | immap = (immap_t *)IMAP_ADDR; | ||
29 | cp = (cpm8xx_t *)&(immap->im_cpm); | ||
30 | |||
31 | /* Reset the CPM. This is necessary on the 860 processors | ||
32 | * that may have started the SCC1 ethernet without relocating | ||
33 | * the IIC. | ||
34 | * This also stops the Ethernet in case we were loaded by a | ||
35 | * BOOTP rom monitor. | ||
36 | */ | ||
37 | cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG); | ||
38 | |||
39 | /* Wait for it. | ||
40 | */ | ||
41 | while (cp->cp_cpcr & (CPM_CR_RST | CPM_CR_FLG)); | ||
42 | |||
43 | /* Remove any microcode patches. We will install our own | ||
44 | * later. | ||
45 | */ | ||
46 | cp->cp_cpmcr1 = 0; | ||
47 | cp->cp_cpmcr2 = 0; | ||
48 | cp->cp_cpmcr3 = 0; | ||
49 | cp->cp_cpmcr4 = 0; | ||
50 | cp->cp_rccr = 0; | ||
51 | |||
52 | iip = (iic_t *)&cp->cp_dparam[PROFF_IIC]; | ||
53 | i2c = (i2c8xx_t *)&(immap->im_i2c); | ||
54 | |||
55 | /* Initialize Port B IIC pins. | ||
56 | */ | ||
57 | cp->cp_pbpar |= 0x00000030; | ||
58 | cp->cp_pbdir |= 0x00000030; | ||
59 | cp->cp_pbodr |= 0x00000030; | ||
60 | |||
61 | /* Initialize the parameter ram. | ||
62 | */ | ||
63 | |||
64 | /* Allocate space for a two transmit and one receive buffer | ||
65 | * descriptor in the DP ram. | ||
66 | * For now, this address seems OK, but it may have to | ||
67 | * change with newer versions of the firmware. | ||
68 | */ | ||
69 | dpaddr = 0x0840; | ||
70 | |||
71 | /* Set up the IIC parameters in the parameter ram. | ||
72 | */ | ||
73 | iip->iic_tbase = dpaddr; | ||
74 | iip->iic_rbase = dpaddr + (2 * sizeof(cbd_t)); | ||
75 | |||
76 | iip->iic_tfcr = SMC_EB; | ||
77 | iip->iic_rfcr = SMC_EB; | ||
78 | |||
79 | /* This should really be done by the reader/writer. | ||
80 | */ | ||
81 | iip->iic_mrblr = 128; | ||
82 | |||
83 | /* Initialize Tx/Rx parameters. | ||
84 | */ | ||
85 | cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG; | ||
86 | while (cp->cp_cpcr & CPM_CR_FLG); | ||
87 | |||
88 | /* Select an arbitrary address. Just make sure it is unique. | ||
89 | */ | ||
90 | i2c->i2c_i2add = 0x34; | ||
91 | |||
92 | /* Make clock run maximum slow. | ||
93 | */ | ||
94 | i2c->i2c_i2brg = 7; | ||
95 | |||
96 | /* Disable interrupts. | ||
97 | */ | ||
98 | i2c->i2c_i2cmr = 0; | ||
99 | i2c->i2c_i2cer = 0xff; | ||
100 | |||
101 | /* Enable SDMA. | ||
102 | */ | ||
103 | immap->im_siu_conf.sc_sdcr = 1; | ||
104 | |||
105 | iic_init_done = 1; | ||
106 | } | ||
107 | |||
108 | /* Read from IIC. | ||
109 | * Caller provides device address, memory buffer, and byte count. | ||
110 | */ | ||
111 | static u_char iitemp[32]; | ||
112 | |||
113 | void | ||
114 | iic_read(uint devaddr, u_char *buf, uint offset, uint count) | ||
115 | { | ||
116 | volatile iic_t *iip; | ||
117 | volatile i2c8xx_t *i2c; | ||
118 | volatile cbd_t *tbdf, *rbdf; | ||
119 | volatile cpm8xx_t *cp; | ||
120 | volatile immap_t *immap; | ||
121 | u_char *tb; | ||
122 | uint temp; | ||
123 | |||
124 | /* If the interface has not been initialized, do that now. | ||
125 | */ | ||
126 | if (!iic_init_done) | ||
127 | iic_init(); | ||
128 | |||
129 | immap = (immap_t *)IMAP_ADDR; | ||
130 | cp = (cpm8xx_t *)&(immap->im_cpm); | ||
131 | |||
132 | iip = (iic_t *)&cp->cp_dparam[PROFF_IIC]; | ||
133 | i2c = (i2c8xx_t *)&(immap->im_i2c); | ||
134 | |||
135 | tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase]; | ||
136 | rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase]; | ||
137 | |||
138 | /* Send a "dummy write" operation. This is a write request with | ||
139 | * only the offset sent, followed by another start condition. | ||
140 | * This will ensure we start reading from the first location | ||
141 | * of the EEPROM. | ||
142 | */ | ||
143 | tb = iitemp; | ||
144 | tb = (u_char *)(((uint)tb + 15) & ~15); | ||
145 | tbdf->cbd_bufaddr = (int)tb; | ||
146 | *tb = devaddr & 0xfe; /* Device address */ | ||
147 | *(tb+1) = offset; /* Offset */ | ||
148 | tbdf->cbd_datlen = 2; /* Length */ | ||
149 | tbdf->cbd_sc = | ||
150 | BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START; | ||
151 | |||
152 | i2c->i2c_i2mod = 1; /* Enable */ | ||
153 | i2c->i2c_i2cer = 0xff; | ||
154 | i2c->i2c_i2com = 0x81; /* Start master */ | ||
155 | |||
156 | /* Wait for IIC transfer. | ||
157 | */ | ||
158 | #if 0 | ||
159 | while ((i2c->i2c_i2cer & 3) == 0); | ||
160 | |||
161 | if (tbdf->cbd_sc & BD_SC_READY) | ||
162 | printf("IIC ra complete but tbuf ready\n"); | ||
163 | #else | ||
164 | temp = 10000000; | ||
165 | while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0)) | ||
166 | temp--; | ||
167 | #if 0 | ||
168 | /* We can't do this...there is no serial port yet! | ||
169 | */ | ||
170 | if (temp == 0) { | ||
171 | printf("Timeout reading EEPROM\n"); | ||
172 | return; | ||
173 | } | ||
174 | #endif | ||
175 | #endif | ||
176 | |||
177 | /* Chip errata, clear enable. | ||
178 | */ | ||
179 | i2c->i2c_i2mod = 0; | ||
180 | |||
181 | /* To read, we need an empty buffer of the proper length. | ||
182 | * All that is used is the first byte for address, the remainder | ||
183 | * is just used for timing (and doesn't really have to exist). | ||
184 | */ | ||
185 | tbdf->cbd_bufaddr = (int)tb; | ||
186 | *tb = devaddr | 1; /* Device address */ | ||
187 | rbdf->cbd_bufaddr = (uint)buf; /* Desination buffer */ | ||
188 | tbdf->cbd_datlen = rbdf->cbd_datlen = count + 1; /* Length */ | ||
189 | tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START; | ||
190 | rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP; | ||
191 | |||
192 | /* Chip bug, set enable here. | ||
193 | */ | ||
194 | i2c->i2c_i2mod = 1; /* Enable */ | ||
195 | i2c->i2c_i2cer = 0xff; | ||
196 | i2c->i2c_i2com = 0x81; /* Start master */ | ||
197 | |||
198 | /* Wait for IIC transfer. | ||
199 | */ | ||
200 | #if 0 | ||
201 | while ((i2c->i2c_i2cer & 1) == 0); | ||
202 | |||
203 | if (rbdf->cbd_sc & BD_SC_EMPTY) | ||
204 | printf("IIC read complete but rbuf empty\n"); | ||
205 | #else | ||
206 | temp = 10000000; | ||
207 | while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0)) | ||
208 | temp--; | ||
209 | #endif | ||
210 | |||
211 | /* Chip errata, clear enable. | ||
212 | */ | ||
213 | i2c->i2c_i2mod = 0; | ||
214 | } | ||
diff --git a/arch/ppc/boot/simple/m8260_tty.c b/arch/ppc/boot/simple/m8260_tty.c new file mode 100644 index 000000000000..d770947e9b8f --- /dev/null +++ b/arch/ppc/boot/simple/m8260_tty.c | |||
@@ -0,0 +1,325 @@ | |||
1 | /* Minimal serial functions needed to send messages out the serial | ||
2 | * port on SMC1. | ||
3 | */ | ||
4 | #include <linux/types.h> | ||
5 | #include <asm/mpc8260.h> | ||
6 | #include <asm/cpm2.h> | ||
7 | #include <asm/immap_cpm2.h> | ||
8 | |||
9 | uint no_print; | ||
10 | extern char *params[]; | ||
11 | extern int nparams; | ||
12 | static u_char cons_hold[128], *sgptr; | ||
13 | static int cons_hold_cnt; | ||
14 | |||
15 | /* If defined, enables serial console. The value (1 through 4) | ||
16 | * should designate which SCC is used, but this isn't complete. Only | ||
17 | * SCC1 is known to work at this time. | ||
18 | * We're only linked if SERIAL_CPM_CONSOLE=y, so we only need to test | ||
19 | * SERIAL_CPM_SCC1. | ||
20 | */ | ||
21 | #ifdef CONFIG_SERIAL_CPM_SCC1 | ||
22 | #define SCC_CONSOLE 1 | ||
23 | #endif | ||
24 | |||
25 | unsigned long | ||
26 | serial_init(int ignored, bd_t *bd) | ||
27 | { | ||
28 | #ifdef SCC_CONSOLE | ||
29 | volatile scc_t *sccp; | ||
30 | volatile scc_uart_t *sup; | ||
31 | #else | ||
32 | volatile smc_t *sp; | ||
33 | volatile smc_uart_t *up; | ||
34 | #endif | ||
35 | volatile cbd_t *tbdf, *rbdf; | ||
36 | volatile cpm2_map_t *ip; | ||
37 | volatile iop_cpm2_t *io; | ||
38 | volatile cpm_cpm2_t *cp; | ||
39 | uint dpaddr, memaddr; | ||
40 | |||
41 | ip = (cpm2_map_t *)CPM_MAP_ADDR; | ||
42 | cp = &ip->im_cpm; | ||
43 | io = &ip->im_ioport; | ||
44 | |||
45 | /* Perform a reset. | ||
46 | */ | ||
47 | cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG); | ||
48 | |||
49 | /* Wait for it. | ||
50 | */ | ||
51 | while (cp->cp_cpcr & CPM_CR_FLG); | ||
52 | |||
53 | #ifdef CONFIG_ADS8260 | ||
54 | /* Enable the RS-232 transceivers. | ||
55 | */ | ||
56 | *(volatile uint *)(BCSR_ADDR + 4) &= | ||
57 | ~(BCSR1_RS232_EN1 | BCSR1_RS232_EN2); | ||
58 | #endif | ||
59 | |||
60 | #ifdef SCC_CONSOLE | ||
61 | sccp = (scc_t *)&(ip->im_scc[SCC_CONSOLE-1]); | ||
62 | sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; | ||
63 | sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); | ||
64 | sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | ||
65 | |||
66 | /* Use Port D for SCC1 instead of other functions. | ||
67 | */ | ||
68 | io->iop_ppard |= 0x00000003; | ||
69 | io->iop_psord &= ~0x00000001; /* Rx */ | ||
70 | io->iop_psord |= 0x00000002; /* Tx */ | ||
71 | io->iop_pdird &= ~0x00000001; /* Rx */ | ||
72 | io->iop_pdird |= 0x00000002; /* Tx */ | ||
73 | |||
74 | #else | ||
75 | sp = (smc_t*)&(ip->im_smc[0]); | ||
76 | *(ushort *)(&ip->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1; | ||
77 | up = (smc_uart_t *)&ip->im_dprambase[PROFF_SMC1]; | ||
78 | |||
79 | /* Disable transmitter/receiver. | ||
80 | */ | ||
81 | sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); | ||
82 | |||
83 | /* Use Port D for SMC1 instead of other functions. | ||
84 | */ | ||
85 | io->iop_ppard |= 0x00c00000; | ||
86 | io->iop_pdird |= 0x00400000; | ||
87 | io->iop_pdird &= ~0x00800000; | ||
88 | io->iop_psord &= ~0x00c00000; | ||
89 | #endif | ||
90 | |||
91 | /* Allocate space for two buffer descriptors in the DP ram. | ||
92 | * For now, this address seems OK, but it may have to | ||
93 | * change with newer versions of the firmware. | ||
94 | */ | ||
95 | dpaddr = 0x0800; | ||
96 | |||
97 | /* Grab a few bytes from the top of memory. | ||
98 | */ | ||
99 | memaddr = (bd->bi_memsize - 256) & ~15; | ||
100 | |||
101 | /* Set the physical address of the host memory buffers in | ||
102 | * the buffer descriptors. | ||
103 | */ | ||
104 | rbdf = (cbd_t *)&ip->im_dprambase[dpaddr]; | ||
105 | rbdf->cbd_bufaddr = memaddr; | ||
106 | rbdf->cbd_sc = 0; | ||
107 | tbdf = rbdf + 1; | ||
108 | tbdf->cbd_bufaddr = memaddr+128; | ||
109 | tbdf->cbd_sc = 0; | ||
110 | |||
111 | /* Set up the uart parameters in the parameter ram. | ||
112 | */ | ||
113 | #ifdef SCC_CONSOLE | ||
114 | sup->scc_genscc.scc_rbase = dpaddr; | ||
115 | sup->scc_genscc.scc_tbase = dpaddr + sizeof(cbd_t); | ||
116 | |||
117 | /* Set up the uart parameters in the | ||
118 | * parameter ram. | ||
119 | */ | ||
120 | sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; | ||
121 | sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB; | ||
122 | |||
123 | sup->scc_genscc.scc_mrblr = 128; | ||
124 | sup->scc_maxidl = 8; | ||
125 | sup->scc_brkcr = 1; | ||
126 | sup->scc_parec = 0; | ||
127 | sup->scc_frmec = 0; | ||
128 | sup->scc_nosec = 0; | ||
129 | sup->scc_brkec = 0; | ||
130 | sup->scc_uaddr1 = 0; | ||
131 | sup->scc_uaddr2 = 0; | ||
132 | sup->scc_toseq = 0; | ||
133 | sup->scc_char1 = 0x8000; | ||
134 | sup->scc_char2 = 0x8000; | ||
135 | sup->scc_char3 = 0x8000; | ||
136 | sup->scc_char4 = 0x8000; | ||
137 | sup->scc_char5 = 0x8000; | ||
138 | sup->scc_char6 = 0x8000; | ||
139 | sup->scc_char7 = 0x8000; | ||
140 | sup->scc_char8 = 0x8000; | ||
141 | sup->scc_rccm = 0xc0ff; | ||
142 | |||
143 | /* Send the CPM an initialize command. | ||
144 | */ | ||
145 | cp->cp_cpcr = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0, | ||
146 | CPM_CR_INIT_TRX) | CPM_CR_FLG; | ||
147 | while (cp->cp_cpcr & CPM_CR_FLG); | ||
148 | |||
149 | /* Set UART mode, 8 bit, no parity, one stop. | ||
150 | * Enable receive and transmit. | ||
151 | */ | ||
152 | sccp->scc_gsmrh = 0; | ||
153 | sccp->scc_gsmrl = | ||
154 | (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); | ||
155 | |||
156 | /* Disable all interrupts and clear all pending | ||
157 | * events. | ||
158 | */ | ||
159 | sccp->scc_sccm = 0; | ||
160 | sccp->scc_scce = 0xffff; | ||
161 | sccp->scc_dsr = 0x7e7e; | ||
162 | sccp->scc_psmr = 0x3000; | ||
163 | |||
164 | /* Wire BRG1 to SCC1. The console driver will take care of | ||
165 | * others. | ||
166 | */ | ||
167 | ip->im_cpmux.cmx_scr = 0; | ||
168 | #else | ||
169 | up->smc_rbase = dpaddr; | ||
170 | up->smc_tbase = dpaddr+sizeof(cbd_t); | ||
171 | up->smc_rfcr = CPMFCR_EB; | ||
172 | up->smc_tfcr = CPMFCR_EB; | ||
173 | up->smc_brklen = 0; | ||
174 | up->smc_brkec = 0; | ||
175 | up->smc_brkcr = 0; | ||
176 | up->smc_mrblr = 128; | ||
177 | up->smc_maxidl = 8; | ||
178 | |||
179 | /* Set UART mode, 8 bit, no parity, one stop. | ||
180 | * Enable receive and transmit. | ||
181 | */ | ||
182 | sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; | ||
183 | |||
184 | /* Mask all interrupts and remove anything pending. | ||
185 | */ | ||
186 | sp->smc_smcm = 0; | ||
187 | sp->smc_smce = 0xff; | ||
188 | |||
189 | /* Set up the baud rate generator. | ||
190 | */ | ||
191 | ip->im_cpmux.cmx_smr = 0; | ||
192 | #endif | ||
193 | |||
194 | /* The baud rate divisor needs to be coordinated with clk_8260(). | ||
195 | */ | ||
196 | ip->im_brgc1 = | ||
197 | (((bd->bi_brgfreq/16) / bd->bi_baudrate) << 1) | | ||
198 | CPM_BRG_EN; | ||
199 | |||
200 | /* Make the first buffer the only buffer. | ||
201 | */ | ||
202 | tbdf->cbd_sc |= BD_SC_WRAP; | ||
203 | rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; | ||
204 | |||
205 | /* Initialize Tx/Rx parameters. | ||
206 | */ | ||
207 | #ifdef SCC_CONSOLE | ||
208 | sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); | ||
209 | #else | ||
210 | cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; | ||
211 | while (cp->cp_cpcr & CPM_CR_FLG); | ||
212 | |||
213 | /* Enable transmitter/receiver. | ||
214 | */ | ||
215 | sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; | ||
216 | #endif | ||
217 | |||
218 | /* This is ignored. | ||
219 | */ | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | int | ||
224 | serial_readbuf(u_char *cbuf) | ||
225 | { | ||
226 | volatile cbd_t *rbdf; | ||
227 | volatile char *buf; | ||
228 | #ifdef SCC_CONSOLE | ||
229 | volatile scc_uart_t *sup; | ||
230 | #else | ||
231 | volatile smc_uart_t *up; | ||
232 | #endif | ||
233 | volatile cpm2_map_t *ip; | ||
234 | int i, nc; | ||
235 | |||
236 | ip = (cpm2_map_t *)CPM_MAP_ADDR; | ||
237 | |||
238 | #ifdef SCC_CONSOLE | ||
239 | sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; | ||
240 | rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase]; | ||
241 | #else | ||
242 | up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); | ||
243 | rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase]; | ||
244 | #endif | ||
245 | |||
246 | /* Wait for character to show up. | ||
247 | */ | ||
248 | buf = (char *)rbdf->cbd_bufaddr; | ||
249 | while (rbdf->cbd_sc & BD_SC_EMPTY); | ||
250 | nc = rbdf->cbd_datlen; | ||
251 | for (i=0; i<nc; i++) | ||
252 | *cbuf++ = *buf++; | ||
253 | rbdf->cbd_sc |= BD_SC_EMPTY; | ||
254 | |||
255 | return(nc); | ||
256 | } | ||
257 | |||
258 | void | ||
259 | serial_putc(void *ignored, const char c) | ||
260 | { | ||
261 | volatile cbd_t *tbdf; | ||
262 | volatile char *buf; | ||
263 | #ifdef SCC_CONSOLE | ||
264 | volatile scc_uart_t *sup; | ||
265 | #else | ||
266 | volatile smc_uart_t *up; | ||
267 | #endif | ||
268 | volatile cpm2_map_t *ip; | ||
269 | |||
270 | ip = (cpm2_map_t *)CPM_MAP_ADDR; | ||
271 | #ifdef SCC_CONSOLE | ||
272 | sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; | ||
273 | tbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_tbase]; | ||
274 | #else | ||
275 | up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); | ||
276 | tbdf = (cbd_t *)&ip->im_dprambase[up->smc_tbase]; | ||
277 | #endif | ||
278 | |||
279 | /* Wait for last character to go. | ||
280 | */ | ||
281 | buf = (char *)tbdf->cbd_bufaddr; | ||
282 | while (tbdf->cbd_sc & BD_SC_READY); | ||
283 | |||
284 | *buf = c; | ||
285 | tbdf->cbd_datlen = 1; | ||
286 | tbdf->cbd_sc |= BD_SC_READY; | ||
287 | } | ||
288 | |||
289 | char | ||
290 | serial_getc(void *ignored) | ||
291 | { | ||
292 | char c; | ||
293 | |||
294 | if (cons_hold_cnt <= 0) { | ||
295 | cons_hold_cnt = serial_readbuf(cons_hold); | ||
296 | sgptr = cons_hold; | ||
297 | } | ||
298 | c = *sgptr++; | ||
299 | cons_hold_cnt--; | ||
300 | |||
301 | return(c); | ||
302 | } | ||
303 | |||
304 | int | ||
305 | serial_tstc(void *ignored) | ||
306 | { | ||
307 | volatile cbd_t *rbdf; | ||
308 | #ifdef SCC_CONSOLE | ||
309 | volatile scc_uart_t *sup; | ||
310 | #else | ||
311 | volatile smc_uart_t *up; | ||
312 | #endif | ||
313 | volatile cpm2_map_t *ip; | ||
314 | |||
315 | ip = (cpm2_map_t *)CPM_MAP_ADDR; | ||
316 | #ifdef SCC_CONSOLE | ||
317 | sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; | ||
318 | rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase]; | ||
319 | #else | ||
320 | up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); | ||
321 | rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase]; | ||
322 | #endif | ||
323 | |||
324 | return(!(rbdf->cbd_sc & BD_SC_EMPTY)); | ||
325 | } | ||
diff --git a/arch/ppc/boot/simple/m8xx_tty.c b/arch/ppc/boot/simple/m8xx_tty.c new file mode 100644 index 000000000000..1d2778e248c6 --- /dev/null +++ b/arch/ppc/boot/simple/m8xx_tty.c | |||
@@ -0,0 +1,290 @@ | |||
1 | /* Minimal serial functions needed to send messages out the serial | ||
2 | * port on the MBX console. | ||
3 | * | ||
4 | * The MBX uxes SMC1 for the serial port. We reset the port and use | ||
5 | * only the first BD that EPPC-Bug set up as a character FIFO. | ||
6 | * | ||
7 | * Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug | ||
8 | * use COM1 instead of SMC1 as the console port. This kinda sucks | ||
9 | * for the rest of the kernel, so here we force the use of SMC1 again. | ||
10 | */ | ||
11 | #include <linux/config.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <asm/uaccess.h> | ||
14 | #include <asm/mpc8xx.h> | ||
15 | #include <asm/commproc.h> | ||
16 | |||
17 | #ifdef CONFIG_MBX | ||
18 | #define MBX_CSR1 ((volatile u_char *)0xfa100000) | ||
19 | #define CSR1_COMEN (u_char)0x02 | ||
20 | #endif | ||
21 | |||
22 | #ifdef TQM_SMC2_CONSOLE | ||
23 | #define PROFF_CONS PROFF_SMC2 | ||
24 | #define CPM_CR_CH_CONS CPM_CR_CH_SMC2 | ||
25 | #define SMC_INDEX 1 | ||
26 | static volatile iop8xx_t *iopp = (iop8xx_t *)&(((immap_t *)IMAP_ADDR)->im_ioport); | ||
27 | #else | ||
28 | #define PROFF_CONS PROFF_SMC1 | ||
29 | #define CPM_CR_CH_CONS CPM_CR_CH_SMC1 | ||
30 | #define SMC_INDEX 0 | ||
31 | #endif | ||
32 | |||
33 | static cpm8xx_t *cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); | ||
34 | |||
35 | unsigned long | ||
36 | serial_init(int ignored, bd_t *bd) | ||
37 | { | ||
38 | volatile smc_t *sp; | ||
39 | volatile smc_uart_t *up; | ||
40 | volatile cbd_t *tbdf, *rbdf; | ||
41 | volatile cpm8xx_t *cp; | ||
42 | uint dpaddr, memaddr; | ||
43 | #ifndef CONFIG_MBX | ||
44 | uint ui; | ||
45 | #endif | ||
46 | |||
47 | cp = cpmp; | ||
48 | sp = (smc_t*)&(cp->cp_smc[SMC_INDEX]); | ||
49 | up = (smc_uart_t *)&cp->cp_dparam[PROFF_CONS]; | ||
50 | |||
51 | /* Disable transmitter/receiver. | ||
52 | */ | ||
53 | sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); | ||
54 | |||
55 | #ifdef CONFIG_FADS | ||
56 | /* Enable SMC1/2 transceivers. | ||
57 | */ | ||
58 | *((volatile uint *)BCSR1) &= ~(BCSR1_RS232EN_1|BCSR1_RS232EN_2); | ||
59 | #endif | ||
60 | |||
61 | #ifndef CONFIG_MBX | ||
62 | { | ||
63 | /* Initialize SMCx and use it for the console port. | ||
64 | */ | ||
65 | |||
66 | /* Enable SDMA. | ||
67 | */ | ||
68 | ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; | ||
69 | |||
70 | #ifdef TQM_SMC2_CONSOLE | ||
71 | /* Use Port A for SMC2 instead of other functions. | ||
72 | */ | ||
73 | iopp->iop_papar |= 0x00c0; | ||
74 | iopp->iop_padir &= ~0x00c0; | ||
75 | iopp->iop_paodr &= ~0x00c0; | ||
76 | #else | ||
77 | /* Use Port B for SMCs instead of other functions. | ||
78 | */ | ||
79 | cp->cp_pbpar |= 0x00000cc0; | ||
80 | cp->cp_pbdir &= ~0x00000cc0; | ||
81 | cp->cp_pbodr &= ~0x00000cc0; | ||
82 | #endif | ||
83 | |||
84 | /* Allocate space for two buffer descriptors in the DP ram. | ||
85 | * For now, this address seems OK, but it may have to | ||
86 | * change with newer versions of the firmware. | ||
87 | */ | ||
88 | dpaddr = 0x0800; | ||
89 | |||
90 | /* Grab a few bytes from the top of memory for SMC FIFOs. | ||
91 | */ | ||
92 | memaddr = (bd->bi_memsize - 32) & ~15; | ||
93 | |||
94 | /* Set the physical address of the host memory buffers in | ||
95 | * the buffer descriptors. | ||
96 | */ | ||
97 | rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; | ||
98 | rbdf->cbd_bufaddr = memaddr; | ||
99 | rbdf->cbd_sc = 0; | ||
100 | tbdf = rbdf + 1; | ||
101 | tbdf->cbd_bufaddr = memaddr+4; | ||
102 | tbdf->cbd_sc = 0; | ||
103 | |||
104 | /* Set up the uart parameters in the parameter ram. | ||
105 | */ | ||
106 | up->smc_rbase = dpaddr; | ||
107 | up->smc_tbase = dpaddr+sizeof(cbd_t); | ||
108 | up->smc_rfcr = SMC_EB; | ||
109 | up->smc_tfcr = SMC_EB; | ||
110 | |||
111 | /* Set UART mode, 8 bit, no parity, one stop. | ||
112 | * Enable receive and transmit. | ||
113 | */ | ||
114 | sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; | ||
115 | |||
116 | /* Mask all interrupts and remove anything pending. | ||
117 | */ | ||
118 | sp->smc_smcm = 0; | ||
119 | sp->smc_smce = 0xff; | ||
120 | |||
121 | /* Set up the baud rate generator. | ||
122 | * See 8xx_io/commproc.c for details. | ||
123 | * This wires BRG1 to SMC1 and BRG2 to SMC2; | ||
124 | */ | ||
125 | cp->cp_simode = 0x10000000; | ||
126 | ui = bd->bi_intfreq / 16 / bd->bi_baudrate; | ||
127 | #ifdef TQM_SMC2_CONSOLE | ||
128 | cp->cp_brgc2 = | ||
129 | #else | ||
130 | cp->cp_brgc1 = | ||
131 | #endif | ||
132 | ((ui - 1) < 4096) | ||
133 | ? (((ui - 1) << 1) | CPM_BRG_EN) | ||
134 | : ((((ui / 16) - 1) << 1) | CPM_BRG_EN | CPM_BRG_DIV16); | ||
135 | |||
136 | #else /* CONFIG_MBX */ | ||
137 | if (*MBX_CSR1 & CSR1_COMEN) { | ||
138 | /* COM1 is enabled. Initialize SMC1 and use it for | ||
139 | * the console port. | ||
140 | */ | ||
141 | |||
142 | /* Enable SDMA. | ||
143 | */ | ||
144 | ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; | ||
145 | |||
146 | /* Use Port B for SMCs instead of other functions. | ||
147 | */ | ||
148 | cp->cp_pbpar |= 0x00000cc0; | ||
149 | cp->cp_pbdir &= ~0x00000cc0; | ||
150 | cp->cp_pbodr &= ~0x00000cc0; | ||
151 | |||
152 | /* Allocate space for two buffer descriptors in the DP ram. | ||
153 | * For now, this address seems OK, but it may have to | ||
154 | * change with newer versions of the firmware. | ||
155 | */ | ||
156 | dpaddr = 0x0800; | ||
157 | |||
158 | /* Grab a few bytes from the top of memory. EPPC-Bug isn't | ||
159 | * running any more, so we can do this. | ||
160 | */ | ||
161 | memaddr = (bd->bi_memsize - 32) & ~15; | ||
162 | |||
163 | /* Set the physical address of the host memory buffers in | ||
164 | * the buffer descriptors. | ||
165 | */ | ||
166 | rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; | ||
167 | rbdf->cbd_bufaddr = memaddr; | ||
168 | rbdf->cbd_sc = 0; | ||
169 | tbdf = rbdf + 1; | ||
170 | tbdf->cbd_bufaddr = memaddr+4; | ||
171 | tbdf->cbd_sc = 0; | ||
172 | |||
173 | /* Set up the uart parameters in the parameter ram. | ||
174 | */ | ||
175 | up->smc_rbase = dpaddr; | ||
176 | up->smc_tbase = dpaddr+sizeof(cbd_t); | ||
177 | up->smc_rfcr = SMC_EB; | ||
178 | up->smc_tfcr = SMC_EB; | ||
179 | |||
180 | /* Set UART mode, 8 bit, no parity, one stop. | ||
181 | * Enable receive and transmit. | ||
182 | */ | ||
183 | sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; | ||
184 | |||
185 | /* Mask all interrupts and remove anything pending. | ||
186 | */ | ||
187 | sp->smc_smcm = 0; | ||
188 | sp->smc_smce = 0xff; | ||
189 | |||
190 | /* Set up the baud rate generator. | ||
191 | * See 8xx_io/commproc.c for details. | ||
192 | */ | ||
193 | cp->cp_simode = 0x10000000; | ||
194 | cp->cp_brgc1 = | ||
195 | (((bd->bi_intfreq/16) / 9600) << 1) | CPM_BRG_EN; | ||
196 | |||
197 | /* Enable SMC1 for console output. | ||
198 | */ | ||
199 | *MBX_CSR1 &= ~CSR1_COMEN; | ||
200 | } | ||
201 | else { | ||
202 | #endif /* ndef CONFIG_MBX */ | ||
203 | /* SMCx is used as console port. | ||
204 | */ | ||
205 | tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase]; | ||
206 | rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase]; | ||
207 | |||
208 | /* Issue a stop transmit, and wait for it. | ||
209 | */ | ||
210 | cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, | ||
211 | CPM_CR_STOP_TX) | CPM_CR_FLG; | ||
212 | while (cp->cp_cpcr & CPM_CR_FLG); | ||
213 | } | ||
214 | |||
215 | /* Make the first buffer the only buffer. | ||
216 | */ | ||
217 | tbdf->cbd_sc |= BD_SC_WRAP; | ||
218 | rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; | ||
219 | |||
220 | /* Single character receive. | ||
221 | */ | ||
222 | up->smc_mrblr = 1; | ||
223 | up->smc_maxidl = 0; | ||
224 | |||
225 | /* Initialize Tx/Rx parameters. | ||
226 | */ | ||
227 | cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_INIT_TRX) | CPM_CR_FLG; | ||
228 | while (cp->cp_cpcr & CPM_CR_FLG); | ||
229 | |||
230 | /* Enable transmitter/receiver. | ||
231 | */ | ||
232 | sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; | ||
233 | |||
234 | /* This is ignored. | ||
235 | */ | ||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | void | ||
240 | serial_putc(void *ignored, const char c) | ||
241 | { | ||
242 | volatile cbd_t *tbdf; | ||
243 | volatile char *buf; | ||
244 | volatile smc_uart_t *up; | ||
245 | |||
246 | up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; | ||
247 | tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase]; | ||
248 | |||
249 | /* Wait for last character to go. | ||
250 | */ | ||
251 | buf = (char *)tbdf->cbd_bufaddr; | ||
252 | while (tbdf->cbd_sc & BD_SC_READY); | ||
253 | |||
254 | *buf = c; | ||
255 | tbdf->cbd_datlen = 1; | ||
256 | tbdf->cbd_sc |= BD_SC_READY; | ||
257 | } | ||
258 | |||
259 | char | ||
260 | serial_getc(void *ignored) | ||
261 | { | ||
262 | volatile cbd_t *rbdf; | ||
263 | volatile char *buf; | ||
264 | volatile smc_uart_t *up; | ||
265 | char c; | ||
266 | |||
267 | up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; | ||
268 | rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; | ||
269 | |||
270 | /* Wait for character to show up. | ||
271 | */ | ||
272 | buf = (char *)rbdf->cbd_bufaddr; | ||
273 | while (rbdf->cbd_sc & BD_SC_EMPTY); | ||
274 | c = *buf; | ||
275 | rbdf->cbd_sc |= BD_SC_EMPTY; | ||
276 | |||
277 | return(c); | ||
278 | } | ||
279 | |||
280 | int | ||
281 | serial_tstc(void *ignored) | ||
282 | { | ||
283 | volatile cbd_t *rbdf; | ||
284 | volatile smc_uart_t *up; | ||
285 | |||
286 | up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; | ||
287 | rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; | ||
288 | |||
289 | return(!(rbdf->cbd_sc & BD_SC_EMPTY)); | ||
290 | } | ||
diff --git a/arch/ppc/boot/simple/misc-chestnut.c b/arch/ppc/boot/simple/misc-chestnut.c new file mode 100644 index 000000000000..0dce7f3557e4 --- /dev/null +++ b/arch/ppc/boot/simple/misc-chestnut.c | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/misc-chestnut.c | ||
3 | * | ||
4 | * Setup for the IBM Chestnut (ibm-750fxgx_eval) | ||
5 | * | ||
6 | * Author: Mark A. Greer <mgreer@mvista.com> | ||
7 | * | ||
8 | * 2005 (c) MontaVista Software, Inc. This file is licensed under | ||
9 | * the terms of the GNU General Public License version 2. This program | ||
10 | * is licensed "as is" without any warranty of any kind, whether express | ||
11 | * or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <asm/io.h> | ||
17 | #include <asm/mv64x60_defs.h> | ||
18 | #include <platforms/chestnut.h> | ||
19 | |||
20 | /* Not in the kernel so won't include kernel.h to get its 'max' definition */ | ||
21 | #define max(a,b) (((a) > (b)) ? (a) : (b)) | ||
22 | |||
23 | void | ||
24 | mv64x60_board_init(void __iomem *old_base, void __iomem *new_base) | ||
25 | { | ||
26 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
27 | /* | ||
28 | * Change device bus 2 window so that bootoader can do I/O thru | ||
29 | * 8250/16550 UART that's mapped in that window. | ||
30 | */ | ||
31 | out_le32(new_base + MV64x60_CPU2DEV_2_BASE, CHESTNUT_UART_BASE >> 16); | ||
32 | out_le32(new_base + MV64x60_CPU2DEV_2_SIZE, CHESTNUT_UART_SIZE >> 16); | ||
33 | __asm__ __volatile__("sync"); | ||
34 | #endif | ||
35 | } | ||
diff --git a/arch/ppc/boot/simple/misc-cpci690.c b/arch/ppc/boot/simple/misc-cpci690.c new file mode 100644 index 000000000000..ef08e86c9b25 --- /dev/null +++ b/arch/ppc/boot/simple/misc-cpci690.c | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/misc-cpci690.c | ||
3 | * | ||
4 | * Add birec data for Force CPCI690 board. | ||
5 | * | ||
6 | * Author: Mark A. Greer <source@mvista.com> | ||
7 | * | ||
8 | * 2003 (c) MontaVista Software, Inc. This file is licensed under | ||
9 | * the terms of the GNU General Public License version 2. This program | ||
10 | * is licensed "as is" without any warranty of any kind, whether express | ||
11 | * or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/types.h> | ||
15 | #include <platforms/cpci690.h> | ||
16 | |||
17 | extern u32 mv64x60_console_baud; | ||
18 | extern u32 mv64x60_mpsc_clk_src; | ||
19 | extern u32 mv64x60_mpsc_clk_freq; | ||
20 | |||
21 | void | ||
22 | mv64x60_board_init(void __iomem *old_base, void __iomem *new_base) | ||
23 | { | ||
24 | mv64x60_console_baud = CPCI690_MPSC_BAUD; | ||
25 | mv64x60_mpsc_clk_src = CPCI690_MPSC_CLK_SRC; | ||
26 | mv64x60_mpsc_clk_freq = CPCI690_BUS_FREQ; | ||
27 | } | ||
diff --git a/arch/ppc/boot/simple/misc-embedded.c b/arch/ppc/boot/simple/misc-embedded.c new file mode 100644 index 000000000000..3865f3f8dcd1 --- /dev/null +++ b/arch/ppc/boot/simple/misc-embedded.c | |||
@@ -0,0 +1,275 @@ | |||
1 | /* | ||
2 | * Originally adapted by Gary Thomas. Much additional work by | ||
3 | * Cort Dougan <cort@fsmlabs.com>. On top of that still more work by | ||
4 | * Dan Malek <dmalek@jlc.net>. | ||
5 | * | ||
6 | * Currently maintained by: Tom Rini <trini@kernel.crashing.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/config.h> | ||
10 | #include <linux/types.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <asm/bootinfo.h> | ||
13 | #include <asm/mmu.h> | ||
14 | #include <asm/page.h> | ||
15 | #include <asm/residual.h> | ||
16 | #if defined(CONFIG_4xx) | ||
17 | #include <asm/ibm4xx.h> | ||
18 | #elif defined(CONFIG_8xx) | ||
19 | #include <asm/mpc8xx.h> | ||
20 | #elif defined(CONFIG_8260) | ||
21 | #include <asm/mpc8260.h> | ||
22 | #endif | ||
23 | |||
24 | #include "nonstdio.h" | ||
25 | |||
26 | /* The linker tells us where the image is. */ | ||
27 | extern char __image_begin, __image_end; | ||
28 | extern char __ramdisk_begin, __ramdisk_end; | ||
29 | extern char _end[]; | ||
30 | |||
31 | /* Because of the limited amount of memory on embedded, it presents | ||
32 | * loading problems. The biggest is that we load this boot program | ||
33 | * into a relatively low memory address, and the Linux kernel Bss often | ||
34 | * extends into this space when it get loaded. When the kernel starts | ||
35 | * and zeros the BSS space, it also writes over the information we | ||
36 | * save here and pass to the kernel (usually board info). | ||
37 | * On these boards, we grab some known memory holes to hold this information. | ||
38 | */ | ||
39 | char cmd_buf[256]; | ||
40 | char *cmd_line = cmd_buf; | ||
41 | char *avail_ram; | ||
42 | char *end_avail; | ||
43 | char *zimage_start; | ||
44 | |||
45 | /* This is for 4xx treeboot. It provides a place for the bootrom | ||
46 | * give us a pointer to a rom environment command line. | ||
47 | */ | ||
48 | char *bootrom_cmdline = ""; | ||
49 | |||
50 | /* This is the default cmdline that will be given to the user at boot time.. | ||
51 | * If none was specified at compile time, we'll give it one that should work. | ||
52 | * -- Tom */ | ||
53 | #ifdef CONFIG_CMDLINE_BOOL | ||
54 | char compiled_string[] = CONFIG_CMDLINE; | ||
55 | #endif | ||
56 | char ramroot_string[] = "root=/dev/ram"; | ||
57 | char netroot_string[] = "root=/dev/nfs rw ip=on"; | ||
58 | |||
59 | /* Serial port to use. */ | ||
60 | unsigned long com_port; | ||
61 | |||
62 | /* We need to make sure that this is before the images to ensure | ||
63 | * that it's in a mapped location. - Tom */ | ||
64 | bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot"))); | ||
65 | bd_t *hold_residual = &hold_resid_buf; | ||
66 | |||
67 | extern unsigned long serial_init(int chan, bd_t *bp); | ||
68 | extern void serial_close(unsigned long com_port); | ||
69 | extern unsigned long start; | ||
70 | extern void flush_instruction_cache(void); | ||
71 | extern void gunzip(void *, int, unsigned char *, int *); | ||
72 | extern void embed_config(bd_t **bp); | ||
73 | |||
74 | /* Weak function for boards which don't need to build the | ||
75 | * board info struct because they are using PPCBoot/U-Boot. | ||
76 | */ | ||
77 | void __attribute__ ((weak)) | ||
78 | embed_config(bd_t **bdp) | ||
79 | { | ||
80 | } | ||
81 | |||
82 | unsigned long | ||
83 | load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *bp) | ||
84 | { | ||
85 | char *cp, ch; | ||
86 | int timer = 0, zimage_size; | ||
87 | unsigned long initrd_size; | ||
88 | |||
89 | /* First, capture the embedded board information. Then | ||
90 | * initialize the serial console port. | ||
91 | */ | ||
92 | embed_config(&bp); | ||
93 | #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) | ||
94 | com_port = serial_init(0, bp); | ||
95 | #endif | ||
96 | |||
97 | /* Grab some space for the command line and board info. Since | ||
98 | * we no longer use the ELF header, but it was loaded, grab | ||
99 | * that space. | ||
100 | */ | ||
101 | #ifdef CONFIG_MBX | ||
102 | /* Because of the way the MBX loads the ELF image, we can't | ||
103 | * tell where we started. We read a magic variable from the NVRAM | ||
104 | * that gives us the intermediate buffer load address. | ||
105 | */ | ||
106 | load_addr = *(uint *)0xfa000020; | ||
107 | load_addr += 0x10000; /* Skip ELF header */ | ||
108 | #endif | ||
109 | /* copy board data */ | ||
110 | if (bp) | ||
111 | memcpy(hold_residual,bp,sizeof(bd_t)); | ||
112 | |||
113 | /* Set end of memory available to us. It is always the highest | ||
114 | * memory address provided by the board information. | ||
115 | */ | ||
116 | end_avail = (char *)(bp->bi_memsize); | ||
117 | |||
118 | puts("\nloaded at: "); puthex(load_addr); | ||
119 | puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); | ||
120 | if ( (unsigned long)load_addr != (unsigned long)&start ) { | ||
121 | puts("relocated to: "); puthex((unsigned long)&start); | ||
122 | puts(" "); | ||
123 | puthex((unsigned long)((unsigned long)&start + (4*num_words))); | ||
124 | puts("\n"); | ||
125 | } | ||
126 | |||
127 | if ( bp ) { | ||
128 | puts("board data at: "); puthex((unsigned long)bp); | ||
129 | puts(" "); | ||
130 | puthex((unsigned long)((unsigned long)bp + sizeof(bd_t))); | ||
131 | puts("\nrelocated to: "); | ||
132 | puthex((unsigned long)hold_residual); | ||
133 | puts(" "); | ||
134 | puthex((unsigned long)((unsigned long)hold_residual + sizeof(bd_t))); | ||
135 | puts("\n"); | ||
136 | } | ||
137 | |||
138 | /* | ||
139 | * We link ourself to an arbitrary low address. When we run, we | ||
140 | * relocate outself to that address. __image_being points to | ||
141 | * the part of the image where the zImage is. -- Tom | ||
142 | */ | ||
143 | zimage_start = (char *)(unsigned long)(&__image_begin); | ||
144 | zimage_size = (unsigned long)(&__image_end) - | ||
145 | (unsigned long)(&__image_begin); | ||
146 | |||
147 | initrd_size = (unsigned long)(&__ramdisk_end) - | ||
148 | (unsigned long)(&__ramdisk_begin); | ||
149 | |||
150 | /* | ||
151 | * The zImage and initrd will be between start and _end, so they've | ||
152 | * already been moved once. We're good to go now. -- Tom | ||
153 | */ | ||
154 | puts("zimage at: "); puthex((unsigned long)zimage_start); | ||
155 | puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); | ||
156 | puts("\n"); | ||
157 | |||
158 | if ( initrd_size ) { | ||
159 | puts("initrd at: "); | ||
160 | puthex((unsigned long)(&__ramdisk_begin)); | ||
161 | puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n"); | ||
162 | } | ||
163 | |||
164 | /* | ||
165 | * setup avail_ram - this is the first part of ram usable | ||
166 | * by the uncompress code. Anything after this program in RAM | ||
167 | * is now fair game. -- Tom | ||
168 | */ | ||
169 | avail_ram = (char *)PAGE_ALIGN((unsigned long)_end); | ||
170 | |||
171 | puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" "); | ||
172 | puthex((unsigned long)end_avail); puts("\n"); | ||
173 | puts("\nLinux/PPC load: "); | ||
174 | cp = cmd_line; | ||
175 | /* This is where we try and pick the right command line for booting. | ||
176 | * If we were given one at compile time, use it. It Is Right. | ||
177 | * If we weren't, see if we have a ramdisk. If so, thats root. | ||
178 | * When in doubt, give them the netroot (root=/dev/nfs rw) -- Tom | ||
179 | */ | ||
180 | #ifdef CONFIG_CMDLINE_BOOL | ||
181 | memcpy (cmd_line, compiled_string, sizeof(compiled_string)); | ||
182 | #else | ||
183 | if ( initrd_size ) | ||
184 | memcpy (cmd_line, ramroot_string, sizeof(ramroot_string)); | ||
185 | else | ||
186 | memcpy (cmd_line, netroot_string, sizeof(netroot_string)); | ||
187 | #endif | ||
188 | while ( *cp ) | ||
189 | putc(*cp++); | ||
190 | while (timer++ < 5*1000) { | ||
191 | if (tstc()) { | ||
192 | while ((ch = getc()) != '\n' && ch != '\r') { | ||
193 | if (ch == '\b' || ch == '\177') { | ||
194 | if (cp != cmd_line) { | ||
195 | cp--; | ||
196 | puts("\b \b"); | ||
197 | } | ||
198 | } else if (ch == '\030' /* ^x */ | ||
199 | || ch == '\025') { /* ^u */ | ||
200 | while (cp != cmd_line) { | ||
201 | cp--; | ||
202 | puts("\b \b"); | ||
203 | } | ||
204 | } else { | ||
205 | *cp++ = ch; | ||
206 | putc(ch); | ||
207 | } | ||
208 | } | ||
209 | break; /* Exit 'timer' loop */ | ||
210 | } | ||
211 | udelay(1000); /* 1 msec */ | ||
212 | } | ||
213 | *cp = 0; | ||
214 | puts("\nUncompressing Linux..."); | ||
215 | |||
216 | gunzip(0, 0x400000, zimage_start, &zimage_size); | ||
217 | flush_instruction_cache(); | ||
218 | puts("done.\n"); | ||
219 | { | ||
220 | struct bi_record *rec; | ||
221 | unsigned long initrd_loc = 0; | ||
222 | unsigned long rec_loc = _ALIGN((unsigned long)(zimage_size) + | ||
223 | (1 << 20) - 1, (1 << 20)); | ||
224 | rec = (struct bi_record *)rec_loc; | ||
225 | |||
226 | /* We need to make sure that the initrd and bi_recs do not | ||
227 | * overlap. */ | ||
228 | if ( initrd_size ) { | ||
229 | initrd_loc = (unsigned long)(&__ramdisk_begin); | ||
230 | /* If the bi_recs are in the middle of the current | ||
231 | * initrd, move the initrd to the next MB | ||
232 | * boundary. */ | ||
233 | if ((rec_loc > initrd_loc) && | ||
234 | ((initrd_loc + initrd_size) | ||
235 | > rec_loc)) { | ||
236 | initrd_loc = _ALIGN((unsigned long)(zimage_size) | ||
237 | + (2 << 20) - 1, (2 << 20)); | ||
238 | memmove((void *)initrd_loc, &__ramdisk_begin, | ||
239 | initrd_size); | ||
240 | puts("initrd moved: "); puthex(initrd_loc); | ||
241 | puts(" "); puthex(initrd_loc + initrd_size); | ||
242 | puts("\n"); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | rec->tag = BI_FIRST; | ||
247 | rec->size = sizeof(struct bi_record); | ||
248 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
249 | |||
250 | rec->tag = BI_CMD_LINE; | ||
251 | memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1); | ||
252 | rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1; | ||
253 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
254 | |||
255 | if ( initrd_size ) { | ||
256 | rec->tag = BI_INITRD; | ||
257 | rec->data[0] = initrd_loc; | ||
258 | rec->data[1] = initrd_size; | ||
259 | rec->size = sizeof(struct bi_record) + 2 * | ||
260 | sizeof(unsigned long); | ||
261 | rec = (struct bi_record *)((unsigned long)rec + | ||
262 | rec->size); | ||
263 | } | ||
264 | |||
265 | rec->tag = BI_LAST; | ||
266 | rec->size = sizeof(struct bi_record); | ||
267 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
268 | } | ||
269 | puts("Now booting the kernel\n"); | ||
270 | #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) | ||
271 | serial_close(com_port); | ||
272 | #endif | ||
273 | |||
274 | return (unsigned long)hold_residual; | ||
275 | } | ||
diff --git a/arch/ppc/boot/simple/misc-ev64260.c b/arch/ppc/boot/simple/misc-ev64260.c new file mode 100644 index 000000000000..52ece6937a7a --- /dev/null +++ b/arch/ppc/boot/simple/misc-ev64260.c | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/misc-ev64260.c | ||
3 | * | ||
4 | * Host bridge init code for the Marvell/Galileo EV-64260-BP evaluation board | ||
5 | * with a GT64260 onboard. | ||
6 | * | ||
7 | * Author: Mark A. Greer <mgreer@mvista.com> | ||
8 | * | ||
9 | * 2001 (c) MontaVista Software, Inc. This file is licensed under | ||
10 | * the terms of the GNU General Public License version 2. This program | ||
11 | * is licensed "as is" without any warranty of any kind, whether express | ||
12 | * or implied. | ||
13 | */ | ||
14 | |||
15 | #include <linux/config.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <asm/reg.h> | ||
18 | #include <asm/io.h> | ||
19 | #include <asm/mv64x60_defs.h> | ||
20 | #include <platforms/ev64260.h> | ||
21 | |||
22 | #ifdef CONFIG_SERIAL_MPSC_CONSOLE | ||
23 | extern u32 mv64x60_console_baud; | ||
24 | extern u32 mv64x60_mpsc_clk_src; | ||
25 | extern u32 mv64x60_mpsc_clk_freq; | ||
26 | #endif | ||
27 | |||
28 | void | ||
29 | mv64x60_board_init(void __iomem *old_base, void __iomem *new_base) | ||
30 | { | ||
31 | u32 p, v; | ||
32 | |||
33 | /* DINK doesn't enable 745x timebase, so enable here (Adrian Cox) */ | ||
34 | p = mfspr(SPRN_PVR); | ||
35 | p >>= 16; | ||
36 | |||
37 | /* Reasonable SWAG at a 745x PVR value */ | ||
38 | if (((p & 0xfff0) == 0x8000) && (p != 0x800c)) { | ||
39 | v = mfspr(SPRN_HID0); | ||
40 | v |= HID0_TBEN; | ||
41 | mtspr(SPRN_HID0, v); | ||
42 | } | ||
43 | |||
44 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
45 | /* | ||
46 | * Change device bus 2 window so that bootoader can do I/O thru | ||
47 | * 8250/16550 UART that's mapped in that window. | ||
48 | */ | ||
49 | out_le32(new_base + MV64x60_CPU2DEV_2_BASE, EV64260_UART_BASE >> 20); | ||
50 | out_le32(new_base + MV64x60_CPU2DEV_2_SIZE, EV64260_UART_END >> 20); | ||
51 | __asm__ __volatile__("sync"); | ||
52 | #elif defined(CONFIG_SERIAL_MPSC_CONSOLE) | ||
53 | mv64x60_console_baud = EV64260_DEFAULT_BAUD; | ||
54 | mv64x60_mpsc_clk_src = EV64260_MPSC_CLK_SRC; | ||
55 | mv64x60_mpsc_clk_freq = EV64260_MPSC_CLK_FREQ; | ||
56 | #endif | ||
57 | } | ||
diff --git a/arch/ppc/boot/simple/misc-katana.c b/arch/ppc/boot/simple/misc-katana.c new file mode 100644 index 000000000000..b6e1bb833157 --- /dev/null +++ b/arch/ppc/boot/simple/misc-katana.c | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/misc-katana.c | ||
3 | * | ||
4 | * Set up MPSC values to bootwrapper can prompt user. | ||
5 | * | ||
6 | * Author: Mark A. Greer <source@mvista.com> | ||
7 | * | ||
8 | * 2004 (c) MontaVista Software, Inc. This file is licensed under | ||
9 | * the terms of the GNU General Public License version 2. This program | ||
10 | * is licensed "as is" without any warranty of any kind, whether express | ||
11 | * or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <asm/io.h> | ||
17 | #include <asm/mv64x60_defs.h> | ||
18 | #include <platforms/katana.h> | ||
19 | |||
20 | extern u32 mv64x60_console_baud; | ||
21 | extern u32 mv64x60_mpsc_clk_src; | ||
22 | extern u32 mv64x60_mpsc_clk_freq; | ||
23 | |||
24 | /* Not in the kernel so won't include kernel.h to get its 'min' definition */ | ||
25 | #ifndef min | ||
26 | #define min(a,b) (((a) < (b)) ? (a) : (b)) | ||
27 | #endif | ||
28 | |||
29 | void | ||
30 | mv64x60_board_init(void __iomem *old_base, void __iomem *new_base) | ||
31 | { | ||
32 | mv64x60_console_baud = KATANA_DEFAULT_BAUD; | ||
33 | mv64x60_mpsc_clk_src = KATANA_MPSC_CLK_SRC; | ||
34 | mv64x60_mpsc_clk_freq = | ||
35 | min(katana_bus_freq((void __iomem *)KATANA_CPLD_BASE), | ||
36 | MV64x60_TCLK_FREQ_MAX); | ||
37 | } | ||
diff --git a/arch/ppc/boot/simple/misc-mv64x60.c b/arch/ppc/boot/simple/misc-mv64x60.c new file mode 100644 index 000000000000..7e88fc6d207d --- /dev/null +++ b/arch/ppc/boot/simple/misc-mv64x60.c | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/misc-mv64x60.c | ||
3 | * | ||
4 | * Relocate bridge's register base and call board specific routine. | ||
5 | * | ||
6 | * Author: Mark A. Greer <source@mvista.com> | ||
7 | * | ||
8 | * 2005 (c) MontaVista Software, Inc. This file is licensed under | ||
9 | * the terms of the GNU General Public License version 2. This program | ||
10 | * is licensed "as is" without any warranty of any kind, whether express | ||
11 | * or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <asm/io.h> | ||
17 | #include <asm/mv64x60_defs.h> | ||
18 | |||
19 | extern struct bi_record *decompress_kernel(unsigned long load_addr, | ||
20 | int num_words, unsigned long cksum); | ||
21 | |||
22 | void | ||
23 | mv64x60_move_base(void __iomem *old_base, void __iomem *new_base) | ||
24 | { | ||
25 | u32 bits, mask, b; | ||
26 | |||
27 | if (old_base != new_base) { | ||
28 | #ifdef CONFIG_GT64260 | ||
29 | bits = 12; | ||
30 | mask = 0x07000000; | ||
31 | #else /* Must be mv64[34]60 */ | ||
32 | bits = 16; | ||
33 | mask = 0x03000000; | ||
34 | #endif | ||
35 | b = in_le32(old_base + MV64x60_INTERNAL_SPACE_DECODE); | ||
36 | b &= mask; | ||
37 | b |= ((u32)new_base >> (32 - bits)); | ||
38 | out_le32(old_base + MV64x60_INTERNAL_SPACE_DECODE, b); | ||
39 | |||
40 | __asm__ __volatile__("sync"); | ||
41 | |||
42 | /* Wait for change to happen (in accordance with the manual) */ | ||
43 | while (in_le32(new_base + MV64x60_INTERNAL_SPACE_DECODE) != b); | ||
44 | } | ||
45 | } | ||
46 | |||
47 | void __attribute__ ((weak)) | ||
48 | mv64x60_board_init(void __iomem *old_base, void __iomem *new_base) | ||
49 | { | ||
50 | } | ||
51 | |||
52 | void * | ||
53 | load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, | ||
54 | void *ign1, void *ign2) | ||
55 | { | ||
56 | mv64x60_move_base((void __iomem *)CONFIG_MV64X60_BASE, | ||
57 | (void __iomem *)CONFIG_MV64X60_NEW_BASE); | ||
58 | mv64x60_board_init((void __iomem *)CONFIG_MV64X60_BASE, | ||
59 | (void __iomem *)CONFIG_MV64X60_NEW_BASE); | ||
60 | return decompress_kernel(load_addr, num_words, cksum); | ||
61 | } | ||
diff --git a/arch/ppc/boot/simple/misc-prep.c b/arch/ppc/boot/simple/misc-prep.c new file mode 100644 index 000000000000..75380ac41669 --- /dev/null +++ b/arch/ppc/boot/simple/misc-prep.c | |||
@@ -0,0 +1,212 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/misc-prep.c | ||
3 | * | ||
4 | * Maintainer: Tom Rini <trini@kernel.crashing.org> | ||
5 | * | ||
6 | * In the past: Gary Thomas, Cort Dougan <cort@cs.nmt.edu> | ||
7 | */ | ||
8 | |||
9 | #include <linux/config.h> | ||
10 | #include <linux/pci_ids.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <asm/residual.h> | ||
13 | #include <asm/string.h> | ||
14 | #include <asm/byteorder.h> | ||
15 | #include "mpc10x.h" | ||
16 | #include "of1275.h" | ||
17 | #include "nonstdio.h" | ||
18 | |||
19 | extern int keyb_present; /* keyboard controller is present by default */ | ||
20 | RESIDUAL hold_resid_buf; | ||
21 | RESIDUAL *hold_residual = &hold_resid_buf; | ||
22 | static void *OFW_interface; /* Pointer to OF, if available. */ | ||
23 | |||
24 | #ifdef CONFIG_VGA_CONSOLE | ||
25 | char *vidmem = (char *)0xC00B8000; | ||
26 | int lines = 25, cols = 80; | ||
27 | int orig_x, orig_y = 24; | ||
28 | #endif /* CONFIG_VGA_CONSOLE */ | ||
29 | |||
30 | extern int CRT_tstc(void); | ||
31 | extern int vga_init(unsigned char *ISA_mem); | ||
32 | extern void gunzip(void *, int, unsigned char *, int *); | ||
33 | extern unsigned long serial_init(int chan, void *ignored); | ||
34 | extern void serial_fixups(void); | ||
35 | extern struct bi_record *decompress_kernel(unsigned long load_addr, | ||
36 | int num_words, unsigned long cksum); | ||
37 | extern void disable_6xx_mmu(void); | ||
38 | extern unsigned long mpc10x_get_mem_size(void); | ||
39 | |||
40 | static void | ||
41 | writel(unsigned int val, unsigned int address) | ||
42 | { | ||
43 | /* Ensure I/O operations complete */ | ||
44 | __asm__ volatile("eieio"); | ||
45 | *(unsigned int *)address = cpu_to_le32(val); | ||
46 | } | ||
47 | |||
48 | #define PCI_CFG_ADDR(dev,off) ((0x80<<24) | (dev<<8) | (off&0xfc)) | ||
49 | #define PCI_CFG_DATA(off) (MPC10X_MAPA_CNFG_DATA+(off&3)) | ||
50 | |||
51 | static void | ||
52 | pci_read_config_32(unsigned char devfn, | ||
53 | unsigned char offset, | ||
54 | unsigned int *val) | ||
55 | { | ||
56 | /* Ensure I/O operations complete */ | ||
57 | __asm__ volatile("eieio"); | ||
58 | *(unsigned int *)PCI_CFG_ADDR(devfn,offset) = | ||
59 | cpu_to_le32(MPC10X_MAPA_CNFG_ADDR); | ||
60 | /* Ensure I/O operations complete */ | ||
61 | __asm__ volatile("eieio"); | ||
62 | *val = le32_to_cpu(*(unsigned int *)PCI_CFG_DATA(offset)); | ||
63 | return; | ||
64 | } | ||
65 | |||
66 | #ifdef CONFIG_VGA_CONSOLE | ||
67 | void | ||
68 | scroll(void) | ||
69 | { | ||
70 | int i; | ||
71 | |||
72 | memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 ); | ||
73 | for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 ) | ||
74 | vidmem[i] = ' '; | ||
75 | } | ||
76 | #endif /* CONFIG_VGA_CONSOLE */ | ||
77 | |||
78 | unsigned long | ||
79 | load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, | ||
80 | RESIDUAL *residual, void *OFW) | ||
81 | { | ||
82 | int start_multi = 0; | ||
83 | unsigned int pci_viddid, pci_did, tulip_pci_base, tulip_base; | ||
84 | |||
85 | /* If we have Open Firmware, initialise it immediately */ | ||
86 | if (OFW) { | ||
87 | OFW_interface = OFW; | ||
88 | ofinit(OFW_interface); | ||
89 | } | ||
90 | |||
91 | board_isa_init(); | ||
92 | #if defined(CONFIG_VGA_CONSOLE) | ||
93 | vga_init((unsigned char *)0xC0000000); | ||
94 | #endif /* CONFIG_VGA_CONSOLE */ | ||
95 | |||
96 | if (residual) { | ||
97 | /* Is this Motorola PPCBug? */ | ||
98 | if ((1 & residual->VitalProductData.FirmwareSupports) && | ||
99 | (1 == residual->VitalProductData.FirmwareSupplier)) { | ||
100 | unsigned char base_mod; | ||
101 | unsigned char board_type = inb(0x801) & 0xF0; | ||
102 | |||
103 | /* | ||
104 | * Reset the onboard 21x4x Ethernet | ||
105 | * Motorola Ethernet is at IDSEL 14 (devfn 0x70) | ||
106 | */ | ||
107 | pci_read_config_32(0x70, 0x00, &pci_viddid); | ||
108 | pci_did = (pci_viddid & 0xffff0000) >> 16; | ||
109 | /* Be sure we've really found a 21x4x chip */ | ||
110 | if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_DEC) && | ||
111 | ((pci_did == PCI_DEVICE_ID_DEC_TULIP_FAST) || | ||
112 | (pci_did == PCI_DEVICE_ID_DEC_TULIP) || | ||
113 | (pci_did == PCI_DEVICE_ID_DEC_TULIP_PLUS) || | ||
114 | (pci_did == PCI_DEVICE_ID_DEC_21142))) { | ||
115 | pci_read_config_32(0x70, | ||
116 | 0x10, | ||
117 | &tulip_pci_base); | ||
118 | /* Get the physical base address */ | ||
119 | tulip_base = | ||
120 | (tulip_pci_base & ~0x03UL) + 0x80000000; | ||
121 | /* Strobe the 21x4x reset bit in CSR0 */ | ||
122 | writel(0x1, tulip_base); | ||
123 | } | ||
124 | |||
125 | /* If this is genesis 2 board then check for no | ||
126 | * keyboard controller and more than one processor. | ||
127 | */ | ||
128 | if (board_type == 0xe0) { | ||
129 | base_mod = inb(0x803); | ||
130 | /* if a MVME2300/2400 or a Sitka then no keyboard */ | ||
131 | if((base_mod == 0xFA) || (base_mod == 0xF9) || | ||
132 | (base_mod == 0xE1)) { | ||
133 | keyb_present = 0; /* no keyboard */ | ||
134 | } | ||
135 | } | ||
136 | /* If this is a multiprocessor system then | ||
137 | * park the other processor so that the | ||
138 | * kernel knows where to find them. | ||
139 | */ | ||
140 | if (residual->MaxNumCpus > 1) | ||
141 | start_multi = 1; | ||
142 | } | ||
143 | memcpy(hold_residual,residual,sizeof(RESIDUAL)); | ||
144 | } | ||
145 | |||
146 | /* Call decompress_kernel */ | ||
147 | decompress_kernel(load_addr, num_words, cksum); | ||
148 | |||
149 | if (start_multi) { | ||
150 | residual->VitalProductData.SmpIar = (unsigned long)0xc0; | ||
151 | residual->Cpus[1].CpuState = CPU_GOOD; | ||
152 | hold_residual->VitalProductData.Reserved5 = 0xdeadbeef; | ||
153 | } | ||
154 | |||
155 | /* Now go and clear out the BATs and ensure that our MSR is | ||
156 | * correct .*/ | ||
157 | disable_6xx_mmu(); | ||
158 | |||
159 | /* Make r3 be a pointer to the residual data. */ | ||
160 | return (unsigned long)hold_residual; | ||
161 | } | ||
162 | |||
163 | unsigned long | ||
164 | get_mem_size(void) | ||
165 | { | ||
166 | unsigned int pci_viddid, pci_did; | ||
167 | |||
168 | /* First, figure out what kind of host bridge we are on. If it's | ||
169 | * an MPC10x, we can ask it directly how much memory it has. | ||
170 | * Otherwise, see if the residual data has anything. This isn't | ||
171 | * the best way, but it can be the only way. If there's nothing, | ||
172 | * assume 32MB. -- Tom. | ||
173 | */ | ||
174 | /* See what our host bridge is. */ | ||
175 | pci_read_config_32(0x00, 0x00, &pci_viddid); | ||
176 | pci_did = (pci_viddid & 0xffff0000) >> 16; | ||
177 | /* See if we are on an MPC10x. */ | ||
178 | if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA) | ||
179 | && ((pci_did == PCI_DEVICE_ID_MOTOROLA_MPC105) | ||
180 | || (pci_did == PCI_DEVICE_ID_MOTOROLA_MPC106) | ||
181 | || (pci_did == PCI_DEVICE_ID_MOTOROLA_MPC107))) | ||
182 | return mpc10x_get_mem_size(); | ||
183 | /* If it's not, see if we have anything in the residual data. */ | ||
184 | else if (hold_residual && hold_residual->TotalMemory) | ||
185 | return hold_residual->TotalMemory; | ||
186 | else if (OFW_interface) { | ||
187 | /* | ||
188 | * This is a 'best guess' check. We want to make sure | ||
189 | * we don't try this on a PReP box without OF | ||
190 | * -- Cort | ||
191 | */ | ||
192 | while (OFW_interface) | ||
193 | { | ||
194 | phandle dev_handle; | ||
195 | int mem_info[2]; | ||
196 | |||
197 | /* get handle to memory description */ | ||
198 | if (!(dev_handle = finddevice("/memory@0"))) | ||
199 | break; | ||
200 | |||
201 | /* get the info */ | ||
202 | if (getprop(dev_handle, "reg", mem_info, | ||
203 | sizeof(mem_info)) != 8) | ||
204 | break; | ||
205 | |||
206 | return mem_info[1]; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | /* Fall back to hard-coding 32MB. */ | ||
211 | return 32*1024*1024; | ||
212 | } | ||
diff --git a/arch/ppc/boot/simple/misc-radstone_ppc7d.c b/arch/ppc/boot/simple/misc-radstone_ppc7d.c new file mode 100644 index 000000000000..569e0d4feeaf --- /dev/null +++ b/arch/ppc/boot/simple/misc-radstone_ppc7d.c | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/misc-radstone_ppc7d.c | ||
3 | * | ||
4 | * Misc data for Radstone PPC7D board. | ||
5 | * | ||
6 | * Author: James Chapman <jchapman@katalix.com> | ||
7 | */ | ||
8 | |||
9 | #include <linux/types.h> | ||
10 | #include <platforms/radstone_ppc7d.h> | ||
11 | |||
12 | #if defined(CONFIG_SERIAL_MPSC_CONSOLE) | ||
13 | extern u32 mv64x60_console_baud; | ||
14 | extern u32 mv64x60_mpsc_clk_src; | ||
15 | extern u32 mv64x60_mpsc_clk_freq; | ||
16 | #endif | ||
17 | |||
18 | void | ||
19 | mv64x60_board_init(void __iomem *old_base, void __iomem *new_base) | ||
20 | { | ||
21 | #if defined(CONFIG_SERIAL_MPSC_CONSOLE) | ||
22 | mv64x60_console_baud = PPC7D_DEFAULT_BAUD; | ||
23 | mv64x60_mpsc_clk_src = PPC7D_MPSC_CLK_SRC; | ||
24 | mv64x60_mpsc_clk_freq = PPC7D_MPSC_CLK_FREQ; | ||
25 | #endif | ||
26 | } | ||
diff --git a/arch/ppc/boot/simple/misc-spruce.c b/arch/ppc/boot/simple/misc-spruce.c new file mode 100644 index 000000000000..d012c39278fd --- /dev/null +++ b/arch/ppc/boot/simple/misc-spruce.c | |||
@@ -0,0 +1,274 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/spruce/misc.c | ||
3 | * | ||
4 | * Misc. bootloader code for IBM Spruce reference platform | ||
5 | * | ||
6 | * Authors: Johnnie Peters <jpeters@mvista.com> | ||
7 | * Matt Porter <mporter@mvista.com> | ||
8 | * | ||
9 | * Derived from arch/ppc/boot/prep/misc.c | ||
10 | * | ||
11 | * 2000-2001 (c) MontaVista, Software, Inc. This file is licensed under | ||
12 | * the terms of the GNU General Public License version 2. This program | ||
13 | * is licensed "as is" without any warranty of any kind, whether express | ||
14 | * or implied. | ||
15 | */ | ||
16 | |||
17 | #include <linux/types.h> | ||
18 | #include <linux/config.h> | ||
19 | #include <linux/pci.h> | ||
20 | |||
21 | #include <asm/bootinfo.h> | ||
22 | |||
23 | extern unsigned long decompress_kernel(unsigned long load_addr, int num_words, | ||
24 | unsigned long cksum); | ||
25 | |||
26 | /* Define some important locations of the Spruce. */ | ||
27 | #define SPRUCE_PCI_CONFIG_ADDR 0xfec00000 | ||
28 | #define SPRUCE_PCI_CONFIG_DATA 0xfec00004 | ||
29 | |||
30 | /* PCI configuration space access routines. */ | ||
31 | unsigned int *pci_config_address = (unsigned int *)SPRUCE_PCI_CONFIG_ADDR; | ||
32 | unsigned char *pci_config_data = (unsigned char *)SPRUCE_PCI_CONFIG_DATA; | ||
33 | |||
34 | void cpc700_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, | ||
35 | unsigned char offset, unsigned char *val) | ||
36 | { | ||
37 | out_le32(pci_config_address, | ||
38 | (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); | ||
39 | |||
40 | *val= (in_le32((unsigned *)pci_config_data) >> (8 * (offset & 3))) & 0xff; | ||
41 | } | ||
42 | |||
43 | void cpc700_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, | ||
44 | unsigned char offset, unsigned char val) | ||
45 | { | ||
46 | out_le32(pci_config_address, | ||
47 | (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); | ||
48 | |||
49 | out_8(pci_config_data + (offset&3), val); | ||
50 | } | ||
51 | |||
52 | void cpc700_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, | ||
53 | unsigned char offset, unsigned short *val) | ||
54 | { | ||
55 | out_le32(pci_config_address, | ||
56 | (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); | ||
57 | |||
58 | *val= in_le16((unsigned short *)(pci_config_data + (offset&3))); | ||
59 | } | ||
60 | |||
61 | void cpc700_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, | ||
62 | unsigned char offset, unsigned short val) | ||
63 | { | ||
64 | out_le32(pci_config_address, | ||
65 | (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); | ||
66 | |||
67 | out_le16((unsigned short *)(pci_config_data + (offset&3)), val); | ||
68 | } | ||
69 | |||
70 | void cpc700_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, | ||
71 | unsigned char offset, unsigned int *val) | ||
72 | { | ||
73 | out_le32(pci_config_address, | ||
74 | (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); | ||
75 | |||
76 | *val= in_le32((unsigned *)pci_config_data); | ||
77 | } | ||
78 | |||
79 | void cpc700_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, | ||
80 | unsigned char offset, unsigned int val) | ||
81 | { | ||
82 | out_le32(pci_config_address, | ||
83 | (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); | ||
84 | |||
85 | out_le32((unsigned *)pci_config_data, val); | ||
86 | } | ||
87 | |||
88 | #define PCNET32_WIO_RDP 0x10 | ||
89 | #define PCNET32_WIO_RAP 0x12 | ||
90 | #define PCNET32_WIO_RESET 0x14 | ||
91 | |||
92 | #define PCNET32_DWIO_RDP 0x10 | ||
93 | #define PCNET32_DWIO_RAP 0x14 | ||
94 | #define PCNET32_DWIO_RESET 0x18 | ||
95 | |||
96 | /* Processor interface config register access */ | ||
97 | #define PIFCFGADDR 0xff500000 | ||
98 | #define PIFCFGDATA 0xff500004 | ||
99 | |||
100 | #define PLBMIFOPT 0x18 /* PLB Master Interface Options */ | ||
101 | |||
102 | #define MEM_MBEN 0x24 | ||
103 | #define MEM_TYPE 0x28 | ||
104 | #define MEM_B1SA 0x3c | ||
105 | #define MEM_B1EA 0x5c | ||
106 | #define MEM_B2SA 0x40 | ||
107 | #define MEM_B2EA 0x60 | ||
108 | |||
109 | unsigned long | ||
110 | get_mem_size(void) | ||
111 | { | ||
112 | int loop; | ||
113 | unsigned long mem_size = 0; | ||
114 | unsigned long mem_mben; | ||
115 | unsigned long mem_type; | ||
116 | unsigned long mem_start; | ||
117 | unsigned long mem_end; | ||
118 | volatile int *mem_addr = (int *)0xff500008; | ||
119 | volatile int *mem_data = (int *)0xff50000c; | ||
120 | |||
121 | /* Get the size of memory from the memory controller. */ | ||
122 | *mem_addr = MEM_MBEN; | ||
123 | asm("sync"); | ||
124 | mem_mben = *mem_data; | ||
125 | asm("sync"); | ||
126 | for(loop = 0; loop < 1000; loop++); | ||
127 | |||
128 | *mem_addr = MEM_TYPE; | ||
129 | asm("sync"); | ||
130 | mem_type = *mem_data; | ||
131 | asm("sync"); | ||
132 | for(loop = 0; loop < 1000; loop++); | ||
133 | |||
134 | *mem_addr = MEM_TYPE; | ||
135 | /* Confirm bank 1 has DRAM memory */ | ||
136 | if ((mem_mben & 0x40000000) && | ||
137 | ((mem_type & 0x30000000) == 0x10000000)) { | ||
138 | *mem_addr = MEM_B1SA; | ||
139 | asm("sync"); | ||
140 | mem_start = *mem_data; | ||
141 | asm("sync"); | ||
142 | for(loop = 0; loop < 1000; loop++); | ||
143 | |||
144 | *mem_addr = MEM_B1EA; | ||
145 | asm("sync"); | ||
146 | mem_end = *mem_data; | ||
147 | asm("sync"); | ||
148 | for(loop = 0; loop < 1000; loop++); | ||
149 | |||
150 | mem_size = mem_end - mem_start + 0x100000; | ||
151 | } | ||
152 | |||
153 | /* Confirm bank 2 has DRAM memory */ | ||
154 | if ((mem_mben & 0x20000000) && | ||
155 | ((mem_type & 0xc000000) == 0x4000000)) { | ||
156 | *mem_addr = MEM_B2SA; | ||
157 | asm("sync"); | ||
158 | mem_start = *mem_data; | ||
159 | asm("sync"); | ||
160 | for(loop = 0; loop < 1000; loop++); | ||
161 | |||
162 | *mem_addr = MEM_B2EA; | ||
163 | asm("sync"); | ||
164 | mem_end = *mem_data; | ||
165 | asm("sync"); | ||
166 | for(loop = 0; loop < 1000; loop++); | ||
167 | |||
168 | mem_size += mem_end - mem_start + 0x100000; | ||
169 | } | ||
170 | return mem_size; | ||
171 | } | ||
172 | |||
173 | unsigned long | ||
174 | load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, | ||
175 | void *ign1, void *ign2) | ||
176 | { | ||
177 | int csr0; | ||
178 | int csr_id; | ||
179 | int pci_devfn; | ||
180 | int found_multi = 0; | ||
181 | unsigned short vendor; | ||
182 | unsigned short device; | ||
183 | unsigned short command; | ||
184 | unsigned char header_type; | ||
185 | unsigned int bar0; | ||
186 | volatile int *pif_addr = (int *)0xff500000; | ||
187 | volatile int *pif_data = (int *)0xff500004; | ||
188 | |||
189 | /* | ||
190 | * Gah, these firmware guys need to learn that hardware | ||
191 | * byte swapping is evil! Disable all hardware byte | ||
192 | * swapping so it doesn't hurt anyone. | ||
193 | */ | ||
194 | *pif_addr = PLBMIFOPT; | ||
195 | asm("sync"); | ||
196 | *pif_data = 0x00000000; | ||
197 | asm("sync"); | ||
198 | |||
199 | /* Search out and turn off the PcNet ethernet boot device. */ | ||
200 | for (pci_devfn = 1; pci_devfn < 0xff; pci_devfn++) { | ||
201 | if (PCI_FUNC(pci_devfn) && !found_multi) | ||
202 | continue; | ||
203 | |||
204 | cpc700_pcibios_read_config_byte(0, pci_devfn, | ||
205 | PCI_HEADER_TYPE, &header_type); | ||
206 | |||
207 | if (!PCI_FUNC(pci_devfn)) | ||
208 | found_multi = header_type & 0x80; | ||
209 | |||
210 | cpc700_pcibios_read_config_word(0, pci_devfn, PCI_VENDOR_ID, | ||
211 | &vendor); | ||
212 | |||
213 | if (vendor != 0xffff) { | ||
214 | cpc700_pcibios_read_config_word(0, pci_devfn, | ||
215 | PCI_DEVICE_ID, &device); | ||
216 | |||
217 | /* If this PCI device is the Lance PCNet board then turn it off */ | ||
218 | if ((vendor == PCI_VENDOR_ID_AMD) && | ||
219 | (device == PCI_DEVICE_ID_AMD_LANCE)) { | ||
220 | |||
221 | /* Turn on I/O Space on the board. */ | ||
222 | cpc700_pcibios_read_config_word(0, pci_devfn, | ||
223 | PCI_COMMAND, &command); | ||
224 | command |= 0x1; | ||
225 | cpc700_pcibios_write_config_word(0, pci_devfn, | ||
226 | PCI_COMMAND, command); | ||
227 | |||
228 | /* Get the I/O space address */ | ||
229 | cpc700_pcibios_read_config_dword(0, pci_devfn, | ||
230 | PCI_BASE_ADDRESS_0, &bar0); | ||
231 | bar0 &= 0xfffffffe; | ||
232 | |||
233 | /* Reset the PCNet Board */ | ||
234 | inl (bar0+PCNET32_DWIO_RESET); | ||
235 | inw (bar0+PCNET32_WIO_RESET); | ||
236 | |||
237 | /* First do a work oriented read of csr0. If the value is | ||
238 | * 4 then this is the correct mode to access the board. | ||
239 | * If not try a double word ortiented read. | ||
240 | */ | ||
241 | outw(0, bar0 + PCNET32_WIO_RAP); | ||
242 | csr0 = inw(bar0 + PCNET32_WIO_RDP); | ||
243 | |||
244 | if (csr0 == 4) { | ||
245 | /* Check the Chip id register */ | ||
246 | outw(88, bar0 + PCNET32_WIO_RAP); | ||
247 | csr_id = inw(bar0 + PCNET32_WIO_RDP); | ||
248 | |||
249 | if (csr_id) { | ||
250 | /* This is the valid mode - set the stop bit */ | ||
251 | outw(0, bar0 + PCNET32_WIO_RAP); | ||
252 | outw(csr0, bar0 + PCNET32_WIO_RDP); | ||
253 | } | ||
254 | } else { | ||
255 | outl(0, bar0 + PCNET32_DWIO_RAP); | ||
256 | csr0 = inl(bar0 + PCNET32_DWIO_RDP); | ||
257 | if (csr0 == 4) { | ||
258 | /* Check the Chip id register */ | ||
259 | outl(88, bar0 + PCNET32_WIO_RAP); | ||
260 | csr_id = inl(bar0 + PCNET32_WIO_RDP); | ||
261 | |||
262 | if (csr_id) { | ||
263 | /* This is the valid mode - set the stop bit*/ | ||
264 | outl(0, bar0 + PCNET32_WIO_RAP); | ||
265 | outl(csr0, bar0 + PCNET32_WIO_RDP); | ||
266 | } | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | } | ||
271 | } | ||
272 | |||
273 | return decompress_kernel(load_addr, num_words, cksum); | ||
274 | } | ||
diff --git a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c new file mode 100644 index 000000000000..ab0f9902cb67 --- /dev/null +++ b/arch/ppc/boot/simple/misc.c | |||
@@ -0,0 +1,284 @@ | |||
1 | /* | ||
2 | * arch/ppc/simple/misc.c | ||
3 | * | ||
4 | * Misc. bootloader code for many machines. This assumes you have are using | ||
5 | * a 6xx/7xx/74xx CPU in your machine. This assumes the chunk of memory | ||
6 | * below 8MB is free. Finally, it assumes you have a NS16550-style uart for | ||
7 | * your serial console. If a machine meets these requirements, it can quite | ||
8 | * likely use this code during boot. | ||
9 | * | ||
10 | * Author: Matt Porter <mporter@mvista.com> | ||
11 | * Derived from arch/ppc/boot/prep/misc.c | ||
12 | * | ||
13 | * 2001 (c) MontaVista, Software, Inc. This file is licensed under | ||
14 | * the terms of the GNU General Public License version 2. This program | ||
15 | * is licensed "as is" without any warranty of any kind, whether express | ||
16 | * or implied. | ||
17 | */ | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | #include <linux/config.h> | ||
21 | #include <linux/string.h> | ||
22 | |||
23 | #include <asm/page.h> | ||
24 | #include <asm/mmu.h> | ||
25 | #include <asm/bootinfo.h> | ||
26 | #ifdef CONFIG_44x | ||
27 | #include <asm/ibm4xx.h> | ||
28 | #endif | ||
29 | #include <asm/reg.h> | ||
30 | |||
31 | #include "nonstdio.h" | ||
32 | |||
33 | /* Default cmdline */ | ||
34 | #ifdef CONFIG_CMDLINE | ||
35 | #define CMDLINE CONFIG_CMDLINE | ||
36 | #else | ||
37 | #define CMDLINE "" | ||
38 | #endif | ||
39 | |||
40 | /* Keyboard (and VGA console)? */ | ||
41 | #ifdef CONFIG_VGA_CONSOLE | ||
42 | #define HAS_KEYB 1 | ||
43 | #else | ||
44 | #define HAS_KEYB 0 | ||
45 | #endif | ||
46 | |||
47 | /* Will / Can the user give input? | ||
48 | * Val Henson has requested that Gemini doesn't wait for the | ||
49 | * user to edit the cmdline or not. | ||
50 | */ | ||
51 | #if (defined(CONFIG_SERIAL_8250_CONSOLE) \ | ||
52 | || defined(CONFIG_VGA_CONSOLE) \ | ||
53 | || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ | ||
54 | || defined(CONFIG_SERIAL_MPSC_CONSOLE)) \ | ||
55 | && !defined(CONFIG_GEMINI) | ||
56 | #define INTERACTIVE_CONSOLE 1 | ||
57 | #endif | ||
58 | |||
59 | char *avail_ram; | ||
60 | char *end_avail; | ||
61 | char *zimage_start; | ||
62 | char cmd_preset[] = CMDLINE; | ||
63 | char cmd_buf[256]; | ||
64 | char *cmd_line = cmd_buf; | ||
65 | int keyb_present = HAS_KEYB; | ||
66 | int zimage_size; | ||
67 | |||
68 | unsigned long com_port; | ||
69 | unsigned long initrd_size = 0; | ||
70 | |||
71 | /* The linker tells us various locations in the image */ | ||
72 | extern char __image_begin, __image_end; | ||
73 | extern char __ramdisk_begin, __ramdisk_end; | ||
74 | extern char _end[]; | ||
75 | /* Original location */ | ||
76 | extern unsigned long start; | ||
77 | |||
78 | extern int CRT_tstc(void); | ||
79 | extern unsigned long serial_init(int chan, void *ignored); | ||
80 | extern void serial_close(unsigned long com_port); | ||
81 | extern void gunzip(void *, int, unsigned char *, int *); | ||
82 | extern void serial_fixups(void); | ||
83 | |||
84 | /* Allow get_mem_size to be hooked into. This is the default. */ | ||
85 | unsigned long __attribute__ ((weak)) | ||
86 | get_mem_size(void) | ||
87 | { | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | struct bi_record * | ||
92 | decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) | ||
93 | { | ||
94 | #ifdef INTERACTIVE_CONSOLE | ||
95 | int timer = 0; | ||
96 | char ch; | ||
97 | #endif | ||
98 | char *cp; | ||
99 | struct bi_record *rec; | ||
100 | unsigned long initrd_loc = 0, TotalMemory = 0; | ||
101 | |||
102 | #if defined(CONFIG_SERIAL_8250_CONSOLE) || defined(CONFIG_SERIAL_MPSC_CONSOLE) | ||
103 | com_port = serial_init(0, NULL); | ||
104 | #endif | ||
105 | |||
106 | #if defined(CONFIG_44x) && defined(PPC44x_EMAC0_MR0) | ||
107 | /* Reset MAL */ | ||
108 | mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); | ||
109 | /* Wait for reset */ | ||
110 | while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; | ||
111 | /* Reset EMAC */ | ||
112 | *(volatile unsigned long *)PPC44x_EMAC0_MR0 = 0x20000000; | ||
113 | __asm__ __volatile__("eieio"); | ||
114 | #endif | ||
115 | |||
116 | /* | ||
117 | * Call get_mem_size(), which is memory controller dependent, | ||
118 | * and we must have the correct file linked in here. | ||
119 | */ | ||
120 | TotalMemory = get_mem_size(); | ||
121 | |||
122 | /* assume the chunk below 8M is free */ | ||
123 | end_avail = (char *)0x00800000; | ||
124 | |||
125 | /* | ||
126 | * Reveal where we were loaded at and where we | ||
127 | * were relocated to. | ||
128 | */ | ||
129 | puts("loaded at: "); puthex(load_addr); | ||
130 | puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); | ||
131 | puts("\n"); | ||
132 | if ( (unsigned long)load_addr != (unsigned long)&start ) | ||
133 | { | ||
134 | puts("relocated to: "); puthex((unsigned long)&start); | ||
135 | puts(" "); | ||
136 | puthex((unsigned long)((unsigned long)&start + (4*num_words))); | ||
137 | puts("\n"); | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * We link ourself to 0x00800000. When we run, we relocate | ||
142 | * ourselves there. So we just need __image_begin for the | ||
143 | * start. -- Tom | ||
144 | */ | ||
145 | zimage_start = (char *)(unsigned long)(&__image_begin); | ||
146 | zimage_size = (unsigned long)(&__image_end) - | ||
147 | (unsigned long)(&__image_begin); | ||
148 | |||
149 | initrd_size = (unsigned long)(&__ramdisk_end) - | ||
150 | (unsigned long)(&__ramdisk_begin); | ||
151 | |||
152 | /* | ||
153 | * The zImage and initrd will be between start and _end, so they've | ||
154 | * already been moved once. We're good to go now. -- Tom | ||
155 | */ | ||
156 | avail_ram = (char *)PAGE_ALIGN((unsigned long)_end); | ||
157 | puts("zimage at: "); puthex((unsigned long)zimage_start); | ||
158 | puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); | ||
159 | puts("\n"); | ||
160 | |||
161 | if ( initrd_size ) { | ||
162 | puts("initrd at: "); | ||
163 | puthex((unsigned long)(&__ramdisk_begin)); | ||
164 | puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n"); | ||
165 | } | ||
166 | |||
167 | avail_ram = (char *)0x00400000; | ||
168 | end_avail = (char *)0x00800000; | ||
169 | puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" "); | ||
170 | puthex((unsigned long)end_avail); puts("\n"); | ||
171 | |||
172 | if (keyb_present) | ||
173 | CRT_tstc(); /* Forces keyboard to be initialized */ | ||
174 | #ifdef CONFIG_GEMINI | ||
175 | /* | ||
176 | * If cmd_line is empty and cmd_preset is not, copy cmd_preset | ||
177 | * to cmd_line. This way we can override cmd_preset with the | ||
178 | * command line from Smon. | ||
179 | */ | ||
180 | |||
181 | if ( (cmd_line[0] == '\0') && (cmd_preset[0] != '\0')) | ||
182 | memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); | ||
183 | #endif | ||
184 | |||
185 | /* Display standard Linux/PPC boot prompt for kernel args */ | ||
186 | puts("\nLinux/PPC load: "); | ||
187 | cp = cmd_line; | ||
188 | memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); | ||
189 | while ( *cp ) putc(*cp++); | ||
190 | |||
191 | #ifdef INTERACTIVE_CONSOLE | ||
192 | /* | ||
193 | * If they have a console, allow them to edit the command line. | ||
194 | * Otherwise, don't bother wasting the five seconds. | ||
195 | */ | ||
196 | while (timer++ < 5*1000) { | ||
197 | if (tstc()) { | ||
198 | while ((ch = getc()) != '\n' && ch != '\r') { | ||
199 | /* Test for backspace/delete */ | ||
200 | if (ch == '\b' || ch == '\177') { | ||
201 | if (cp != cmd_line) { | ||
202 | cp--; | ||
203 | puts("\b \b"); | ||
204 | } | ||
205 | /* Test for ^x/^u (and wipe the line) */ | ||
206 | } else if (ch == '\030' || ch == '\025') { | ||
207 | while (cp != cmd_line) { | ||
208 | cp--; | ||
209 | puts("\b \b"); | ||
210 | } | ||
211 | } else { | ||
212 | *cp++ = ch; | ||
213 | putc(ch); | ||
214 | } | ||
215 | } | ||
216 | break; /* Exit 'timer' loop */ | ||
217 | } | ||
218 | udelay(1000); /* 1 msec */ | ||
219 | } | ||
220 | *cp = 0; | ||
221 | #endif | ||
222 | puts("\n"); | ||
223 | |||
224 | puts("Uncompressing Linux..."); | ||
225 | gunzip(0x0, 0x400000, zimage_start, &zimage_size); | ||
226 | puts("done.\n"); | ||
227 | |||
228 | /* get the bi_rec address */ | ||
229 | rec = bootinfo_addr(zimage_size); | ||
230 | |||
231 | /* We need to make sure that the initrd and bi_recs do not | ||
232 | * overlap. */ | ||
233 | if ( initrd_size ) { | ||
234 | unsigned long rec_loc = (unsigned long) rec; | ||
235 | initrd_loc = (unsigned long)(&__ramdisk_begin); | ||
236 | /* If the bi_recs are in the middle of the current | ||
237 | * initrd, move the initrd to the next MB | ||
238 | * boundary. */ | ||
239 | if ((rec_loc > initrd_loc) && | ||
240 | ((initrd_loc + initrd_size) > rec_loc)) { | ||
241 | initrd_loc = _ALIGN((unsigned long)(zimage_size) | ||
242 | + (2 << 20) - 1, (2 << 20)); | ||
243 | memmove((void *)initrd_loc, &__ramdisk_begin, | ||
244 | initrd_size); | ||
245 | puts("initrd moved: "); puthex(initrd_loc); | ||
246 | puts(" "); puthex(initrd_loc + initrd_size); | ||
247 | puts("\n"); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | bootinfo_init(rec); | ||
252 | if ( TotalMemory ) | ||
253 | bootinfo_append(BI_MEMSIZE, sizeof(int), (void*)&TotalMemory); | ||
254 | |||
255 | bootinfo_append(BI_CMD_LINE, strlen(cmd_line)+1, (void*)cmd_line); | ||
256 | |||
257 | /* add a bi_rec for the initrd if it exists */ | ||
258 | if (initrd_size) { | ||
259 | unsigned long initrd[2]; | ||
260 | |||
261 | initrd[0] = initrd_loc; | ||
262 | initrd[1] = initrd_size; | ||
263 | |||
264 | bootinfo_append(BI_INITRD, sizeof(initrd), &initrd); | ||
265 | } | ||
266 | puts("Now booting the kernel\n"); | ||
267 | serial_close(com_port); | ||
268 | |||
269 | return rec; | ||
270 | } | ||
271 | |||
272 | void __attribute__ ((weak)) | ||
273 | board_isa_init(void) | ||
274 | { | ||
275 | } | ||
276 | |||
277 | /* Allow decompress_kernel to be hooked into. This is the default. */ | ||
278 | void * __attribute__ ((weak)) | ||
279 | load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, | ||
280 | void *ign1, void *ign2) | ||
281 | { | ||
282 | board_isa_init(); | ||
283 | return decompress_kernel(load_addr, num_words, cksum); | ||
284 | } | ||
diff --git a/arch/ppc/boot/simple/mpc10x_memory.c b/arch/ppc/boot/simple/mpc10x_memory.c new file mode 100644 index 000000000000..977daedc14c0 --- /dev/null +++ b/arch/ppc/boot/simple/mpc10x_memory.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/common/mpc10x_common.c | ||
3 | * | ||
4 | * A routine to find out how much memory the machine has. | ||
5 | * | ||
6 | * Based on: | ||
7 | * arch/ppc/kernel/mpc10x_common.c | ||
8 | * | ||
9 | * Author: Mark A. Greer | ||
10 | * mgreer@mvista.com | ||
11 | * | ||
12 | * 2001-2002 (c) MontaVista, Software, Inc. This file is licensed under | ||
13 | * the terms of the GNU General Public License version 2. This program | ||
14 | * is licensed "as is" without any warranty of any kind, whether express | ||
15 | * or implied. | ||
16 | */ | ||
17 | |||
18 | #include <linux/pci.h> | ||
19 | #include <asm/types.h> | ||
20 | #include <asm/io.h> | ||
21 | #include "mpc10x.h" | ||
22 | |||
23 | /* | ||
24 | * *** WARNING - A BAT MUST be set to access the PCI config addr/data regs *** | ||
25 | */ | ||
26 | |||
27 | /* | ||
28 | * PCI config space macros, similar to indirect_xxx and early_xxx macros. | ||
29 | * We assume bus 0. | ||
30 | */ | ||
31 | #define MPC10X_CFG_read(val, addr, type, op) *val = op((type)(addr)) | ||
32 | #define MPC10X_CFG_write(val, addr, type, op) op((type *)(addr), (val)) | ||
33 | |||
34 | #define MPC10X_PCI_OP(rw, size, type, op, mask) \ | ||
35 | static void \ | ||
36 | mpc10x_##rw##_config_##size(unsigned int *cfg_addr, \ | ||
37 | unsigned int *cfg_data, int devfn, int offset, \ | ||
38 | type val) \ | ||
39 | { \ | ||
40 | out_be32(cfg_addr, \ | ||
41 | ((offset & 0xfc) << 24) | (devfn << 16) \ | ||
42 | | (0 << 8) | 0x80); \ | ||
43 | MPC10X_CFG_##rw(val, cfg_data + (offset & mask), type, op); \ | ||
44 | return; \ | ||
45 | } | ||
46 | |||
47 | MPC10X_PCI_OP(read, byte, u8 *, in_8, 3) | ||
48 | MPC10X_PCI_OP(read, dword, u32 *, in_le32, 0) | ||
49 | |||
50 | /* | ||
51 | * Read the memory controller registers to determine the amount of memory in | ||
52 | * the system. This assumes that the firmware has correctly set up the memory | ||
53 | * controller registers. On CONFIG_PPC_PREP, we know we are being called | ||
54 | * under a PReP memory map. On all other machines, we assume we are under | ||
55 | * a CHRP memory map. Further, on CONFIG_PPC_MULTIPLATFORM we must rename | ||
56 | * this function. | ||
57 | */ | ||
58 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
59 | #define get_mem_size mpc10x_get_mem_size | ||
60 | #endif | ||
61 | unsigned long | ||
62 | get_mem_size(void) | ||
63 | { | ||
64 | unsigned int *config_addr, *config_data, val; | ||
65 | unsigned long start, end, total, offset; | ||
66 | int i; | ||
67 | unsigned char bank_enables; | ||
68 | |||
69 | #ifdef CONFIG_PPC_PREP | ||
70 | config_addr = (unsigned int *)MPC10X_MAPA_CNFG_ADDR; | ||
71 | config_data = (unsigned int *)MPC10X_MAPA_CNFG_DATA; | ||
72 | #else | ||
73 | config_addr = (unsigned int *)MPC10X_MAPB_CNFG_ADDR; | ||
74 | config_data = (unsigned int *)MPC10X_MAPB_CNFG_DATA; | ||
75 | #endif | ||
76 | |||
77 | mpc10x_read_config_byte(config_addr, config_data, PCI_DEVFN(0,0), | ||
78 | MPC10X_MCTLR_MEM_BANK_ENABLES, &bank_enables); | ||
79 | |||
80 | total = 0; | ||
81 | |||
82 | for (i = 0; i < 8; i++) { | ||
83 | if (bank_enables & (1 << i)) { | ||
84 | offset = MPC10X_MCTLR_MEM_START_1 + ((i > 3) ? 4 : 0); | ||
85 | mpc10x_read_config_dword(config_addr, config_data, | ||
86 | PCI_DEVFN(0,0), offset, &val); | ||
87 | start = (val >> ((i & 3) << 3)) & 0xff; | ||
88 | |||
89 | offset = MPC10X_MCTLR_EXT_MEM_START_1 + ((i>3) ? 4 : 0); | ||
90 | mpc10x_read_config_dword(config_addr, config_data, | ||
91 | PCI_DEVFN(0,0), offset, &val); | ||
92 | val = (val >> ((i & 3) << 3)) & 0x03; | ||
93 | start = (val << 28) | (start << 20); | ||
94 | |||
95 | offset = MPC10X_MCTLR_MEM_END_1 + ((i > 3) ? 4 : 0); | ||
96 | mpc10x_read_config_dword(config_addr, config_data, | ||
97 | PCI_DEVFN(0,0), offset, &val); | ||
98 | end = (val >> ((i & 3) << 3)) & 0xff; | ||
99 | |||
100 | offset = MPC10X_MCTLR_EXT_MEM_END_1 + ((i > 3) ? 4 : 0); | ||
101 | mpc10x_read_config_dword(config_addr, config_data, | ||
102 | PCI_DEVFN(0,0), offset, &val); | ||
103 | val = (val >> ((i & 3) << 3)) & 0x03; | ||
104 | end = (val << 28) | (end << 20) | 0xfffff; | ||
105 | |||
106 | total += (end - start + 1); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | return total; | ||
111 | } | ||
diff --git a/arch/ppc/boot/simple/mpc52xx_tty.c b/arch/ppc/boot/simple/mpc52xx_tty.c new file mode 100644 index 000000000000..3acc6b7c0727 --- /dev/null +++ b/arch/ppc/boot/simple/mpc52xx_tty.c | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/mpc52xx_tty.c | ||
3 | * | ||
4 | * Minimal serial functions needed to send messages out a MPC52xx | ||
5 | * Programmable Serial Controller (PSC). | ||
6 | * | ||
7 | * Author: Dale Farnsworth <dfarnsworth@mvista.com> | ||
8 | * | ||
9 | * 2003-2004 (c) MontaVista, Software, Inc. This file is licensed under the | ||
10 | * terms of the GNU General Public License version 2. This program is licensed | ||
11 | * "as is" without any warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <asm/uaccess.h> | ||
17 | #include <asm/mpc52xx.h> | ||
18 | #include <asm/mpc52xx_psc.h> | ||
19 | #include <asm/serial.h> | ||
20 | #include <asm/io.h> | ||
21 | #include <asm/time.h> | ||
22 | |||
23 | |||
24 | #ifdef MPC52xx_PF_CONSOLE_PORT | ||
25 | #define MPC52xx_CONSOLE MPC52xx_PSCx_OFFSET(MPC52xx_PF_CONSOLE_PORT) | ||
26 | #define MPC52xx_PSC_CONFIG_SHIFT ((MPC52xx_PF_CONSOLE_PORT-1)<<2) | ||
27 | #else | ||
28 | #error "MPC52xx_PF_CONSOLE_PORT not defined" | ||
29 | #endif | ||
30 | |||
31 | static struct mpc52xx_psc __iomem *psc = | ||
32 | (struct mpc52xx_psc __iomem *) MPC52xx_PA(MPC52xx_CONSOLE); | ||
33 | |||
34 | /* The decrementer counts at the system bus clock frequency | ||
35 | * divided by four. The most accurate time base is connected to the | ||
36 | * rtc. We read the decrementer change during one rtc tick | ||
37 | * and multiply by 4 to get the system bus clock frequency. Since a | ||
38 | * rtc tick is one seconds, and that's pretty long, we change the rtc | ||
39 | * dividers temporarly to set them 64x faster ;) | ||
40 | */ | ||
41 | static int | ||
42 | mpc52xx_ipbfreq(void) | ||
43 | { | ||
44 | struct mpc52xx_rtc __iomem *rtc = | ||
45 | (struct mpc52xx_rtc __iomem *) MPC52xx_PA(MPC52xx_RTC_OFFSET); | ||
46 | struct mpc52xx_cdm __iomem *cdm = | ||
47 | (struct mpc52xx_cdm __iomem *) MPC52xx_PA(MPC52xx_CDM_OFFSET); | ||
48 | int current_time, previous_time; | ||
49 | int tbl_start, tbl_end; | ||
50 | int xlbfreq, ipbfreq; | ||
51 | |||
52 | out_be32(&rtc->dividers, 0x8f1f0000); /* Set RTC 64x faster */ | ||
53 | previous_time = in_be32(&rtc->time); | ||
54 | while ((current_time = in_be32(&rtc->time)) == previous_time) ; | ||
55 | tbl_start = get_tbl(); | ||
56 | previous_time = current_time; | ||
57 | while ((current_time = in_be32(&rtc->time)) == previous_time) ; | ||
58 | tbl_end = get_tbl(); | ||
59 | out_be32(&rtc->dividers, 0xffff0000); /* Restore RTC */ | ||
60 | |||
61 | xlbfreq = (tbl_end - tbl_start) << 8; | ||
62 | ipbfreq = (in_8(&cdm->ipb_clk_sel) & 1) ? xlbfreq / 2 : xlbfreq; | ||
63 | |||
64 | return ipbfreq; | ||
65 | } | ||
66 | |||
67 | unsigned long | ||
68 | serial_init(int ignored, void *ignored2) | ||
69 | { | ||
70 | struct mpc52xx_gpio __iomem *gpio = | ||
71 | (struct mpc52xx_gpio __iomem *) MPC52xx_PA(MPC52xx_GPIO_OFFSET); | ||
72 | int divisor; | ||
73 | int mode1; | ||
74 | int mode2; | ||
75 | u32 val32; | ||
76 | |||
77 | static int been_here = 0; | ||
78 | |||
79 | if (been_here) | ||
80 | return 0; | ||
81 | |||
82 | been_here = 1; | ||
83 | |||
84 | val32 = in_be32(&gpio->port_config); | ||
85 | val32 &= ~(0x7 << MPC52xx_PSC_CONFIG_SHIFT); | ||
86 | val32 |= MPC52xx_GPIO_PSC_CONFIG_UART_WITHOUT_CD | ||
87 | << MPC52xx_PSC_CONFIG_SHIFT; | ||
88 | out_be32(&gpio->port_config, val32); | ||
89 | |||
90 | out_8(&psc->command, MPC52xx_PSC_RST_TX | ||
91 | | MPC52xx_PSC_RX_DISABLE | MPC52xx_PSC_TX_ENABLE); | ||
92 | out_8(&psc->command, MPC52xx_PSC_RST_RX); | ||
93 | |||
94 | out_be32(&psc->sicr, 0x0); | ||
95 | out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); | ||
96 | out_be16(&psc->tfalarm, 0xf8); | ||
97 | |||
98 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1 | ||
99 | | MPC52xx_PSC_RX_ENABLE | ||
100 | | MPC52xx_PSC_TX_ENABLE); | ||
101 | |||
102 | divisor = ((mpc52xx_ipbfreq() | ||
103 | / (CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD * 16)) + 1) >> 1; | ||
104 | |||
105 | mode1 = MPC52xx_PSC_MODE_8_BITS | MPC52xx_PSC_MODE_PARNONE | ||
106 | | MPC52xx_PSC_MODE_ERR; | ||
107 | mode2 = MPC52xx_PSC_MODE_ONE_STOP; | ||
108 | |||
109 | out_8(&psc->ctur, divisor>>8); | ||
110 | out_8(&psc->ctlr, divisor); | ||
111 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); | ||
112 | out_8(&psc->mode, mode1); | ||
113 | out_8(&psc->mode, mode2); | ||
114 | |||
115 | return 0; /* ignored */ | ||
116 | } | ||
117 | |||
118 | void | ||
119 | serial_putc(void *ignored, const char c) | ||
120 | { | ||
121 | serial_init(0, NULL); | ||
122 | |||
123 | while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP)) ; | ||
124 | out_8(&psc->mpc52xx_psc_buffer_8, c); | ||
125 | while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP)) ; | ||
126 | } | ||
127 | |||
128 | char | ||
129 | serial_getc(void *ignored) | ||
130 | { | ||
131 | while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY)) ; | ||
132 | |||
133 | return in_8(&psc->mpc52xx_psc_buffer_8); | ||
134 | } | ||
135 | |||
136 | int | ||
137 | serial_tstc(void *ignored) | ||
138 | { | ||
139 | return (in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY) != 0; | ||
140 | } | ||
diff --git a/arch/ppc/boot/simple/mv64x60_tty.c b/arch/ppc/boot/simple/mv64x60_tty.c new file mode 100644 index 000000000000..5b45eb46b669 --- /dev/null +++ b/arch/ppc/boot/simple/mv64x60_tty.c | |||
@@ -0,0 +1,360 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/mv64x60_tty.c | ||
3 | * | ||
4 | * Bootloader version of the embedded MPSC/UART driver for the Marvell 64x60. | ||
5 | * Note: Due to a GT64260A erratum, DMA will be used for UART input (via SDMA). | ||
6 | * | ||
7 | * Author: Mark A. Greer <mgreer@mvista.com> | ||
8 | * | ||
9 | * 2001 (c) MontaVista Software, Inc. This file is licensed under | ||
10 | * the terms of the GNU General Public License version 2. This program | ||
11 | * is licensed "as is" without any warranty of any kind, whether express | ||
12 | * or implied. | ||
13 | */ | ||
14 | |||
15 | /* This code assumes that the data cache has been disabled (L1, L2, L3). */ | ||
16 | |||
17 | #include <linux/config.h> | ||
18 | #include <linux/types.h> | ||
19 | #include <linux/serial_reg.h> | ||
20 | #include <asm/serial.h> | ||
21 | #include <asm/io.h> | ||
22 | #include <asm/mv64x60_defs.h> | ||
23 | #include <mpsc_defs.h> | ||
24 | |||
25 | u32 mv64x60_console_baud = 9600; | ||
26 | u32 mv64x60_mpsc_clk_src = 8; /* TCLK */ | ||
27 | u32 mv64x60_mpsc_clk_freq = 100000000; | ||
28 | |||
29 | extern void udelay(long); | ||
30 | static void stop_dma(int chan); | ||
31 | |||
32 | static void __iomem *mv64x60_base = (void __iomem *)CONFIG_MV64X60_NEW_BASE; | ||
33 | |||
34 | struct sdma_regs { | ||
35 | u32 sdc; | ||
36 | u32 sdcm; | ||
37 | u32 rx_desc; | ||
38 | u32 rx_buf_ptr; | ||
39 | u32 scrdp; | ||
40 | u32 tx_desc; | ||
41 | u32 sctdp; | ||
42 | u32 sftdp; | ||
43 | }; | ||
44 | |||
45 | static struct sdma_regs sdma_regs[2]; | ||
46 | |||
47 | #define SDMA_REGS_INIT(s, reg_base) { \ | ||
48 | (s)->sdc = (reg_base) + SDMA_SDC; \ | ||
49 | (s)->sdcm = (reg_base) + SDMA_SDCM; \ | ||
50 | (s)->rx_desc = (reg_base) + SDMA_RX_DESC; \ | ||
51 | (s)->rx_buf_ptr = (reg_base) + SDMA_RX_BUF_PTR; \ | ||
52 | (s)->scrdp = (reg_base) + SDMA_SCRDP; \ | ||
53 | (s)->tx_desc = (reg_base) + SDMA_TX_DESC; \ | ||
54 | (s)->sctdp = (reg_base) + SDMA_SCTDP; \ | ||
55 | (s)->sftdp = (reg_base) + SDMA_SFTDP; \ | ||
56 | } | ||
57 | |||
58 | static u32 mpsc_base[2] = { MV64x60_MPSC_0_OFFSET, MV64x60_MPSC_1_OFFSET }; | ||
59 | |||
60 | struct mv64x60_rx_desc { | ||
61 | u16 bufsize; | ||
62 | u16 bytecnt; | ||
63 | u32 cmd_stat; | ||
64 | u32 next_desc_ptr; | ||
65 | u32 buffer; | ||
66 | }; | ||
67 | |||
68 | struct mv64x60_tx_desc { | ||
69 | u16 bytecnt; | ||
70 | u16 shadow; | ||
71 | u32 cmd_stat; | ||
72 | u32 next_desc_ptr; | ||
73 | u32 buffer; | ||
74 | }; | ||
75 | |||
76 | #define MAX_RESET_WAIT 10000 | ||
77 | #define MAX_TX_WAIT 10000 | ||
78 | |||
79 | #define RX_NUM_DESC 2 | ||
80 | #define TX_NUM_DESC 2 | ||
81 | |||
82 | #define RX_BUF_SIZE 32 | ||
83 | #define TX_BUF_SIZE 32 | ||
84 | |||
85 | static struct mv64x60_rx_desc rd[2][RX_NUM_DESC] __attribute__ ((aligned(32))); | ||
86 | static struct mv64x60_tx_desc td[2][TX_NUM_DESC] __attribute__ ((aligned(32))); | ||
87 | |||
88 | static char rx_buf[2][RX_NUM_DESC * RX_BUF_SIZE] __attribute__ ((aligned(32))); | ||
89 | static char tx_buf[2][TX_NUM_DESC * TX_BUF_SIZE] __attribute__ ((aligned(32))); | ||
90 | |||
91 | static int cur_rd[2] = { 0, 0 }; | ||
92 | static int cur_td[2] = { 0, 0 }; | ||
93 | |||
94 | static char chan_initialized[2] = { 0, 0 }; | ||
95 | |||
96 | |||
97 | #define RX_INIT_RDP(rdp) { \ | ||
98 | (rdp)->bufsize = 2; \ | ||
99 | (rdp)->bytecnt = 0; \ | ||
100 | (rdp)->cmd_stat = SDMA_DESC_CMDSTAT_L | SDMA_DESC_CMDSTAT_F | \ | ||
101 | SDMA_DESC_CMDSTAT_O; \ | ||
102 | } | ||
103 | |||
104 | #ifdef CONFIG_MV64360 | ||
105 | static u32 cpu2mem_tab[MV64x60_CPU2MEM_WINDOWS][2] = { | ||
106 | { MV64x60_CPU2MEM_0_BASE, MV64x60_CPU2MEM_0_SIZE }, | ||
107 | { MV64x60_CPU2MEM_1_BASE, MV64x60_CPU2MEM_1_SIZE }, | ||
108 | { MV64x60_CPU2MEM_2_BASE, MV64x60_CPU2MEM_2_SIZE }, | ||
109 | { MV64x60_CPU2MEM_3_BASE, MV64x60_CPU2MEM_3_SIZE } | ||
110 | }; | ||
111 | |||
112 | static u32 com2mem_tab[MV64x60_CPU2MEM_WINDOWS][2] = { | ||
113 | { MV64360_MPSC2MEM_0_BASE, MV64360_MPSC2MEM_0_SIZE }, | ||
114 | { MV64360_MPSC2MEM_1_BASE, MV64360_MPSC2MEM_1_SIZE }, | ||
115 | { MV64360_MPSC2MEM_2_BASE, MV64360_MPSC2MEM_2_SIZE }, | ||
116 | { MV64360_MPSC2MEM_3_BASE, MV64360_MPSC2MEM_3_SIZE } | ||
117 | }; | ||
118 | |||
119 | static u32 dram_selects[MV64x60_CPU2MEM_WINDOWS] = { 0xe, 0xd, 0xb, 0x7 }; | ||
120 | #endif | ||
121 | |||
122 | unsigned long | ||
123 | serial_init(int chan, void *ignored) | ||
124 | { | ||
125 | u32 mpsc_routing_base, sdma_base, brg_bcr, cdv; | ||
126 | int i; | ||
127 | |||
128 | chan = (chan == 1); /* default to chan 0 if anything but 1 */ | ||
129 | |||
130 | if (chan_initialized[chan]) | ||
131 | return chan; | ||
132 | |||
133 | chan_initialized[chan] = 1; | ||
134 | |||
135 | if (chan == 0) { | ||
136 | sdma_base = MV64x60_SDMA_0_OFFSET; | ||
137 | brg_bcr = MV64x60_BRG_0_OFFSET + BRG_BCR; | ||
138 | SDMA_REGS_INIT(&sdma_regs[0], MV64x60_SDMA_0_OFFSET); | ||
139 | } else { | ||
140 | sdma_base = MV64x60_SDMA_1_OFFSET; | ||
141 | brg_bcr = MV64x60_BRG_1_OFFSET + BRG_BCR; | ||
142 | SDMA_REGS_INIT(&sdma_regs[0], MV64x60_SDMA_1_OFFSET); | ||
143 | } | ||
144 | |||
145 | mpsc_routing_base = MV64x60_MPSC_ROUTING_OFFSET; | ||
146 | |||
147 | stop_dma(chan); | ||
148 | |||
149 | /* Set up ring buffers */ | ||
150 | for (i=0; i<RX_NUM_DESC; i++) { | ||
151 | RX_INIT_RDP(&rd[chan][i]); | ||
152 | rd[chan][i].buffer = (u32)&rx_buf[chan][i * RX_BUF_SIZE]; | ||
153 | rd[chan][i].next_desc_ptr = (u32)&rd[chan][i+1]; | ||
154 | } | ||
155 | rd[chan][RX_NUM_DESC - 1].next_desc_ptr = (u32)&rd[chan][0]; | ||
156 | |||
157 | for (i=0; i<TX_NUM_DESC; i++) { | ||
158 | td[chan][i].bytecnt = 0; | ||
159 | td[chan][i].shadow = 0; | ||
160 | td[chan][i].buffer = (u32)&tx_buf[chan][i * TX_BUF_SIZE]; | ||
161 | td[chan][i].cmd_stat = SDMA_DESC_CMDSTAT_F|SDMA_DESC_CMDSTAT_L; | ||
162 | td[chan][i].next_desc_ptr = (u32)&td[chan][i+1]; | ||
163 | } | ||
164 | td[chan][TX_NUM_DESC - 1].next_desc_ptr = (u32)&td[chan][0]; | ||
165 | |||
166 | /* Set MPSC Routing */ | ||
167 | out_le32(mv64x60_base + mpsc_routing_base + MPSC_MRR, 0x3ffffe38); | ||
168 | |||
169 | #ifdef CONFIG_GT64260 | ||
170 | out_le32(mv64x60_base + GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102); | ||
171 | #else /* Must be MV64360 or MV64460 */ | ||
172 | { | ||
173 | u32 enables, prot_bits, v; | ||
174 | |||
175 | /* Set up comm unit to memory mapping windows */ | ||
176 | /* Note: Assumes MV64x60_CPU2MEM_WINDOWS == 4 */ | ||
177 | |||
178 | enables = in_le32(mv64x60_base + MV64360_CPU_BAR_ENABLE) & 0xf; | ||
179 | prot_bits = 0; | ||
180 | |||
181 | for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) { | ||
182 | if (!(enables & (1 << i))) { | ||
183 | v = in_le32(mv64x60_base + cpu2mem_tab[i][0]); | ||
184 | v = ((v & 0xffff) << 16) | (dram_selects[i] << 8); | ||
185 | out_le32(mv64x60_base + com2mem_tab[i][0], v); | ||
186 | |||
187 | v = in_le32(mv64x60_base + cpu2mem_tab[i][1]); | ||
188 | v = (v & 0xffff) << 16; | ||
189 | out_le32(mv64x60_base + com2mem_tab[i][1], v); | ||
190 | |||
191 | prot_bits |= (0x3 << (i << 1)); /* r/w access */ | ||
192 | } | ||
193 | } | ||
194 | |||
195 | out_le32(mv64x60_base + MV64360_MPSC_0_REMAP, 0); | ||
196 | out_le32(mv64x60_base + MV64360_MPSC_1_REMAP, 0); | ||
197 | out_le32(mv64x60_base + MV64360_MPSC2MEM_ACC_PROT_0, prot_bits); | ||
198 | out_le32(mv64x60_base + MV64360_MPSC2MEM_ACC_PROT_1, prot_bits); | ||
199 | out_le32(mv64x60_base + MV64360_MPSC2MEM_BAR_ENABLE, enables); | ||
200 | } | ||
201 | #endif | ||
202 | |||
203 | /* MPSC 0/1 Rx & Tx get clocks BRG0/1 */ | ||
204 | out_le32(mv64x60_base + mpsc_routing_base + MPSC_RCRR, 0x00000100); | ||
205 | out_le32(mv64x60_base + mpsc_routing_base + MPSC_TCRR, 0x00000100); | ||
206 | |||
207 | /* clear pending interrupts */ | ||
208 | out_le32(mv64x60_base + MV64x60_SDMA_INTR_OFFSET + SDMA_INTR_MASK, 0); | ||
209 | |||
210 | out_le32(mv64x60_base + SDMA_SCRDP + sdma_base, (int)&rd[chan][0]); | ||
211 | out_le32(mv64x60_base + SDMA_SCTDP + sdma_base, | ||
212 | (int)&td[chan][TX_NUM_DESC - 1]); | ||
213 | out_le32(mv64x60_base + SDMA_SFTDP + sdma_base, | ||
214 | (int)&td[chan][TX_NUM_DESC - 1]); | ||
215 | |||
216 | out_le32(mv64x60_base + SDMA_SDC + sdma_base, | ||
217 | SDMA_SDC_RFT | SDMA_SDC_SFM | SDMA_SDC_BLMR | SDMA_SDC_BLMT | | ||
218 | (3 << 12)); | ||
219 | |||
220 | cdv = ((mv64x60_mpsc_clk_freq/(32*mv64x60_console_baud))-1); | ||
221 | out_le32(mv64x60_base + brg_bcr, | ||
222 | ((mv64x60_mpsc_clk_src << 18) | (1 << 16) | cdv)); | ||
223 | |||
224 | /* Put MPSC into UART mode, no null modem, 16x clock mode */ | ||
225 | out_le32(mv64x60_base + MPSC_MMCRL + mpsc_base[chan], 0x000004c4); | ||
226 | out_le32(mv64x60_base + MPSC_MMCRH + mpsc_base[chan], 0x04400400); | ||
227 | |||
228 | out_le32(mv64x60_base + MPSC_CHR_1 + mpsc_base[chan], 0); | ||
229 | out_le32(mv64x60_base + MPSC_CHR_9 + mpsc_base[chan], 0); | ||
230 | out_le32(mv64x60_base + MPSC_CHR_10 + mpsc_base[chan], 0); | ||
231 | out_le32(mv64x60_base + MPSC_CHR_3 + mpsc_base[chan], 4); | ||
232 | out_le32(mv64x60_base + MPSC_CHR_4 + mpsc_base[chan], 0); | ||
233 | out_le32(mv64x60_base + MPSC_CHR_5 + mpsc_base[chan], 0); | ||
234 | out_le32(mv64x60_base + MPSC_CHR_6 + mpsc_base[chan], 0); | ||
235 | out_le32(mv64x60_base + MPSC_CHR_7 + mpsc_base[chan], 0); | ||
236 | out_le32(mv64x60_base + MPSC_CHR_8 + mpsc_base[chan], 0); | ||
237 | |||
238 | /* 8 data bits, 1 stop bit */ | ||
239 | out_le32(mv64x60_base + MPSC_MPCR + mpsc_base[chan], (3 << 12)); | ||
240 | out_le32(mv64x60_base + SDMA_SDCM + sdma_base, SDMA_SDCM_ERD); | ||
241 | out_le32(mv64x60_base + MPSC_CHR_2 + mpsc_base[chan], MPSC_CHR_2_EH); | ||
242 | |||
243 | udelay(100); | ||
244 | |||
245 | return chan; | ||
246 | } | ||
247 | |||
248 | static void | ||
249 | stop_dma(int chan) | ||
250 | { | ||
251 | int i; | ||
252 | |||
253 | /* Abort MPSC Rx (aborting Tx messes things up) */ | ||
254 | out_le32(mv64x60_base + MPSC_CHR_2 + mpsc_base[chan], MPSC_CHR_2_RA); | ||
255 | |||
256 | /* Abort SDMA Rx, Tx */ | ||
257 | out_le32(mv64x60_base + sdma_regs[chan].sdcm, | ||
258 | SDMA_SDCM_AR | SDMA_SDCM_STD); | ||
259 | |||
260 | for (i=0; i<MAX_RESET_WAIT; i++) { | ||
261 | if ((in_le32(mv64x60_base + sdma_regs[chan].sdcm) & | ||
262 | (SDMA_SDCM_AR | SDMA_SDCM_AT)) == 0) | ||
263 | break; | ||
264 | |||
265 | udelay(100); | ||
266 | } | ||
267 | } | ||
268 | |||
269 | static int | ||
270 | wait_for_ownership(int chan) | ||
271 | { | ||
272 | int i; | ||
273 | |||
274 | for (i=0; i<MAX_TX_WAIT; i++) { | ||
275 | if ((in_le32(mv64x60_base + sdma_regs[chan].sdcm) & | ||
276 | SDMA_SDCM_TXD) == 0) | ||
277 | break; | ||
278 | |||
279 | udelay(1000); | ||
280 | } | ||
281 | |||
282 | return (i < MAX_TX_WAIT); | ||
283 | } | ||
284 | |||
285 | void | ||
286 | serial_putc(unsigned long com_port, unsigned char c) | ||
287 | { | ||
288 | struct mv64x60_tx_desc *tdp; | ||
289 | |||
290 | if (wait_for_ownership(com_port) == 0) | ||
291 | return; | ||
292 | |||
293 | tdp = &td[com_port][cur_td[com_port]]; | ||
294 | if (++cur_td[com_port] >= TX_NUM_DESC) | ||
295 | cur_td[com_port] = 0; | ||
296 | |||
297 | *(unchar *)(tdp->buffer ^ 7) = c; | ||
298 | tdp->bytecnt = 1; | ||
299 | tdp->shadow = 1; | ||
300 | tdp->cmd_stat = SDMA_DESC_CMDSTAT_L | SDMA_DESC_CMDSTAT_F | | ||
301 | SDMA_DESC_CMDSTAT_O; | ||
302 | |||
303 | out_le32(mv64x60_base + sdma_regs[com_port].sctdp, (int)tdp); | ||
304 | out_le32(mv64x60_base + sdma_regs[com_port].sftdp, (int)tdp); | ||
305 | out_le32(mv64x60_base + sdma_regs[com_port].sdcm, | ||
306 | in_le32(mv64x60_base + sdma_regs[com_port].sdcm) | | ||
307 | SDMA_SDCM_TXD); | ||
308 | } | ||
309 | |||
310 | unsigned char | ||
311 | serial_getc(unsigned long com_port) | ||
312 | { | ||
313 | struct mv64x60_rx_desc *rdp; | ||
314 | unchar c = '\0'; | ||
315 | |||
316 | rdp = &rd[com_port][cur_rd[com_port]]; | ||
317 | |||
318 | if ((rdp->cmd_stat & (SDMA_DESC_CMDSTAT_O|SDMA_DESC_CMDSTAT_ES)) == 0) { | ||
319 | c = *(unchar *)(rdp->buffer ^ 7); | ||
320 | RX_INIT_RDP(rdp); | ||
321 | if (++cur_rd[com_port] >= RX_NUM_DESC) | ||
322 | cur_rd[com_port] = 0; | ||
323 | } | ||
324 | |||
325 | return c; | ||
326 | } | ||
327 | |||
328 | int | ||
329 | serial_tstc(unsigned long com_port) | ||
330 | { | ||
331 | struct mv64x60_rx_desc *rdp; | ||
332 | int loop_count = 0; | ||
333 | int rc = 0; | ||
334 | |||
335 | rdp = &rd[com_port][cur_rd[com_port]]; | ||
336 | |||
337 | /* Go thru rcv desc's until empty looking for one with data (no error)*/ | ||
338 | while (((rdp->cmd_stat & SDMA_DESC_CMDSTAT_O) == 0) && | ||
339 | (loop_count++ < RX_NUM_DESC)) { | ||
340 | |||
341 | /* If there was an error, reinit the desc & continue */ | ||
342 | if ((rdp->cmd_stat & SDMA_DESC_CMDSTAT_ES) != 0) { | ||
343 | RX_INIT_RDP(rdp); | ||
344 | if (++cur_rd[com_port] >= RX_NUM_DESC) | ||
345 | cur_rd[com_port] = 0; | ||
346 | rdp = (struct mv64x60_rx_desc *)rdp->next_desc_ptr; | ||
347 | } else { | ||
348 | rc = 1; | ||
349 | break; | ||
350 | } | ||
351 | } | ||
352 | |||
353 | return rc; | ||
354 | } | ||
355 | |||
356 | void | ||
357 | serial_close(unsigned long com_port) | ||
358 | { | ||
359 | stop_dma(com_port); | ||
360 | } | ||
diff --git a/arch/ppc/boot/simple/openbios.c b/arch/ppc/boot/simple/openbios.c new file mode 100644 index 000000000000..c732b6d70cfb --- /dev/null +++ b/arch/ppc/boot/simple/openbios.c | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/openbios.c | ||
3 | * | ||
4 | * 2005 (c) SYSGO AG - g.jaeger@sysgo.com | ||
5 | * This file is licensed under the terms of the GNU General Public | ||
6 | * License version 2. This program is licensed "as is" without | ||
7 | * any warranty of any kind, whether express or implied. | ||
8 | * | ||
9 | * Derived from arch/ppc/boot/simple/pibs.c (from MontaVista) | ||
10 | */ | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | #include <linux/config.h> | ||
14 | #include <linux/string.h> | ||
15 | #include <asm/ppcboot.h> | ||
16 | #include <platforms/4xx/ebony.h> | ||
17 | |||
18 | extern unsigned long decompress_kernel(unsigned long load_addr, int num_words, | ||
19 | unsigned long cksum); | ||
20 | |||
21 | /* We need to make sure that this is before the images to ensure | ||
22 | * that it's in a mapped location. */ | ||
23 | bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot"))); | ||
24 | bd_t *hold_residual = &hold_resid_buf; | ||
25 | |||
26 | void * | ||
27 | load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, | ||
28 | void *ign1, void *ign2) | ||
29 | { | ||
30 | decompress_kernel(load_addr, num_words, cksum); | ||
31 | |||
32 | /* simply copy the MAC addresses */ | ||
33 | memcpy(hold_residual->bi_enetaddr, (char *)EBONY_OPENBIOS_MAC_BASE, 6); | ||
34 | memcpy(hold_residual->bi_enet1addr, (char *)(EBONY_OPENBIOS_MAC_BASE+EBONY_OPENBIOS_MAC_OFFSET), 6); | ||
35 | |||
36 | return (void *)hold_residual; | ||
37 | } | ||
diff --git a/arch/ppc/boot/simple/pci.c b/arch/ppc/boot/simple/pci.c new file mode 100644 index 000000000000..b0f673c8b7d9 --- /dev/null +++ b/arch/ppc/boot/simple/pci.c | |||
@@ -0,0 +1,274 @@ | |||
1 | /* Stand alone funtions for QSpan Tundra support. | ||
2 | */ | ||
3 | #include <linux/types.h> | ||
4 | #include <linux/pci.h> | ||
5 | #include <asm/mpc8xx.h> | ||
6 | |||
7 | extern void puthex(unsigned long val); | ||
8 | extern void puts(const char *); | ||
9 | |||
10 | /* To map PCI devices, you first write 0xffffffff into the device | ||
11 | * base address registers. When the register is read back, the | ||
12 | * number of most significant '1' bits describes the amount of address | ||
13 | * space needed for mapping. If the most significant bit is not set, | ||
14 | * either the device does not use that address register, or it has | ||
15 | * a fixed address that we can't change. After the address is assigned, | ||
16 | * the command register has to be written to enable the card. | ||
17 | */ | ||
18 | typedef struct { | ||
19 | u_char pci_bus; | ||
20 | u_char pci_devfn; | ||
21 | ushort pci_command; | ||
22 | uint pci_addrs[6]; | ||
23 | } pci_map_t; | ||
24 | |||
25 | /* We should probably dynamically allocate these structures. | ||
26 | */ | ||
27 | #define MAX_PCI_DEVS 32 | ||
28 | int pci_dev_cnt; | ||
29 | pci_map_t pci_map[MAX_PCI_DEVS]; | ||
30 | |||
31 | void pci_conf_write(int bus, int device, int func, int reg, uint writeval); | ||
32 | void pci_conf_read(int bus, int device, int func, int reg, void *readval); | ||
33 | void probe_addresses(int bus, int devfn); | ||
34 | void map_pci_addrs(void); | ||
35 | |||
36 | extern int | ||
37 | qs_pci_read_config_byte(unsigned char bus, unsigned char dev_fn, | ||
38 | unsigned char offset, unsigned char *val); | ||
39 | extern int | ||
40 | qs_pci_read_config_word(unsigned char bus, unsigned char dev_fn, | ||
41 | unsigned char offset, unsigned short *val); | ||
42 | extern int | ||
43 | qs_pci_read_config_dword(unsigned char bus, unsigned char dev_fn, | ||
44 | unsigned char offset, unsigned int *val); | ||
45 | extern int | ||
46 | qs_pci_write_config_byte(unsigned char bus, unsigned char dev_fn, | ||
47 | unsigned char offset, unsigned char val); | ||
48 | extern int | ||
49 | qs_pci_write_config_word(unsigned char bus, unsigned char dev_fn, | ||
50 | unsigned char offset, unsigned short val); | ||
51 | extern int | ||
52 | qs_pci_write_config_dword(unsigned char bus, unsigned char dev_fn, | ||
53 | unsigned char offset, unsigned int val); | ||
54 | |||
55 | |||
56 | /* This is a really stripped version of PCI bus scan. All we are | ||
57 | * looking for are devices that exist. | ||
58 | */ | ||
59 | void | ||
60 | pci_scanner(int addr_probe) | ||
61 | { | ||
62 | unsigned int devfn, l, class, bus_number; | ||
63 | unsigned char hdr_type, is_multi; | ||
64 | |||
65 | is_multi = 0; | ||
66 | bus_number = 0; | ||
67 | for (devfn = 0; devfn < 0xff; ++devfn) { | ||
68 | /* The device numbers are comprised of upper 5 bits of | ||
69 | * device number and lower 3 bits of multi-function number. | ||
70 | */ | ||
71 | if ((devfn & 7) && !is_multi) { | ||
72 | /* Don't scan multifunction addresses if this is | ||
73 | * not a multifunction device. | ||
74 | */ | ||
75 | continue; | ||
76 | } | ||
77 | |||
78 | /* Read the header to determine card type. | ||
79 | */ | ||
80 | qs_pci_read_config_byte(bus_number, devfn, PCI_HEADER_TYPE, | ||
81 | &hdr_type); | ||
82 | |||
83 | /* If this is a base device number, check the header to | ||
84 | * determine if it is mulifunction. | ||
85 | */ | ||
86 | if ((devfn & 7) == 0) | ||
87 | is_multi = hdr_type & 0x80; | ||
88 | |||
89 | /* Check to see if the board is really in the slot. | ||
90 | */ | ||
91 | qs_pci_read_config_dword(bus_number, devfn, PCI_VENDOR_ID, &l); | ||
92 | /* some broken boards return 0 if a slot is empty: */ | ||
93 | if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || | ||
94 | l == 0xffff0000) { | ||
95 | /* Nothing there. | ||
96 | */ | ||
97 | is_multi = 0; | ||
98 | continue; | ||
99 | } | ||
100 | |||
101 | /* If we are not performing an address probe, | ||
102 | * just simply print out some information. | ||
103 | */ | ||
104 | if (!addr_probe) { | ||
105 | qs_pci_read_config_dword(bus_number, devfn, | ||
106 | PCI_CLASS_REVISION, &class); | ||
107 | |||
108 | class >>= 8; /* upper 3 bytes */ | ||
109 | |||
110 | #if 0 | ||
111 | printf("Found (%3d:%d): vendor 0x%04x, device 0x%04x, class 0x%06x\n", | ||
112 | (devfn >> 3), (devfn & 7), | ||
113 | (l & 0xffff), (l >> 16) & 0xffff, class); | ||
114 | #else | ||
115 | puts("Found ("); puthex(devfn >> 3); | ||
116 | puts(":"); puthex(devfn & 7); | ||
117 | puts("): vendor "); puthex(l & 0xffff); | ||
118 | puts(", device "); puthex((l >> 16) & 0xffff); | ||
119 | puts(", class "); puthex(class); puts("\n"); | ||
120 | #endif | ||
121 | } | ||
122 | else { | ||
123 | /* If this is a "normal" device, build address list. | ||
124 | */ | ||
125 | if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_NORMAL) | ||
126 | probe_addresses(bus_number, devfn); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | /* Now map the boards. | ||
131 | */ | ||
132 | if (addr_probe) | ||
133 | map_pci_addrs(); | ||
134 | } | ||
135 | |||
136 | /* Probe addresses for the specified device. This is a destructive | ||
137 | * operation because it writes the registers. | ||
138 | */ | ||
139 | void | ||
140 | probe_addresses(bus, devfn) | ||
141 | { | ||
142 | int i; | ||
143 | uint pciaddr; | ||
144 | ushort pcicmd; | ||
145 | pci_map_t *pm; | ||
146 | |||
147 | if (pci_dev_cnt >= MAX_PCI_DEVS) { | ||
148 | puts("Too many PCI devices\n"); | ||
149 | return; | ||
150 | } | ||
151 | |||
152 | pm = &pci_map[pci_dev_cnt++]; | ||
153 | |||
154 | pm->pci_bus = bus; | ||
155 | pm->pci_devfn = devfn; | ||
156 | |||
157 | for (i=0; i<6; i++) { | ||
158 | qs_pci_write_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4), -1); | ||
159 | qs_pci_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4), | ||
160 | &pciaddr); | ||
161 | pm->pci_addrs[i] = pciaddr; | ||
162 | qs_pci_read_config_word(bus, devfn, PCI_COMMAND, &pcicmd); | ||
163 | pm->pci_command = pcicmd; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | /* Map the cards into the PCI space. The PCI has separate memory | ||
168 | * and I/O spaces. In addition, some memory devices require mapping | ||
169 | * below 1M. The least significant 4 bits of the address register | ||
170 | * provide information. If this is an I/O device, only the LS bit | ||
171 | * is used to indicate that, so I/O devices can be mapped to a two byte | ||
172 | * boundard. Memory addresses can be mapped to a 32 byte boundary. | ||
173 | * The QSpan implementations usually have a 1Gbyte space for each | ||
174 | * memory and I/O spaces. | ||
175 | * | ||
176 | * This isn't a terribly fancy algorithm. I just map the spaces from | ||
177 | * the top starting with the largest address space. When finished, | ||
178 | * the registers are written and the card enabled. | ||
179 | * | ||
180 | * While the Tundra can map a large address space on most boards, we | ||
181 | * need to be careful because it may overlap other devices (like IMMR). | ||
182 | */ | ||
183 | #define MEMORY_SPACE_SIZE 0x20000000 | ||
184 | #define IO_SPACE_SIZE 0x20000000 | ||
185 | |||
186 | void | ||
187 | map_pci_addrs() | ||
188 | { | ||
189 | uint pci_mem_top, pci_mem_low; | ||
190 | uint pci_io_top; | ||
191 | uint addr_mask, reg_addr, space; | ||
192 | int i, j; | ||
193 | pci_map_t *pm; | ||
194 | |||
195 | pci_mem_top = MEMORY_SPACE_SIZE; | ||
196 | pci_io_top = IO_SPACE_SIZE; | ||
197 | pci_mem_low = (1 * 1024 * 1024); /* Below one meg addresses */ | ||
198 | |||
199 | /* We can't map anything more than the maximum space, but test | ||
200 | * for it anyway to catch devices out of range. | ||
201 | */ | ||
202 | addr_mask = 0x80000000; | ||
203 | |||
204 | do { | ||
205 | space = (~addr_mask) + 1; /* Size of the space */ | ||
206 | for (i=0; i<pci_dev_cnt; i++) { | ||
207 | pm = &pci_map[i]; | ||
208 | for (j=0; j<6; j++) { | ||
209 | /* If the MS bit is not set, this has either | ||
210 | * already been mapped, or is not used. | ||
211 | */ | ||
212 | reg_addr = pm->pci_addrs[j]; | ||
213 | if ((reg_addr & 0x80000000) == 0) | ||
214 | continue; | ||
215 | if (reg_addr & PCI_BASE_ADDRESS_SPACE_IO) { | ||
216 | if ((reg_addr & PCI_BASE_ADDRESS_IO_MASK) != addr_mask) | ||
217 | continue; | ||
218 | if (pci_io_top < space) { | ||
219 | puts("Out of PCI I/O space\n"); | ||
220 | } | ||
221 | else { | ||
222 | pci_io_top -= space; | ||
223 | pm->pci_addrs[j] = pci_io_top; | ||
224 | pm->pci_command |= PCI_COMMAND_IO; | ||
225 | } | ||
226 | } | ||
227 | else { | ||
228 | if ((reg_addr & PCI_BASE_ADDRESS_MEM_MASK) != addr_mask) | ||
229 | continue; | ||
230 | |||
231 | /* Memory space. Test if below 1M. | ||
232 | */ | ||
233 | if (reg_addr & PCI_BASE_ADDRESS_MEM_TYPE_1M) { | ||
234 | if (pci_mem_low < space) { | ||
235 | puts("Out of PCI 1M space\n"); | ||
236 | } | ||
237 | else { | ||
238 | pci_mem_low -= space; | ||
239 | pm->pci_addrs[j] = pci_mem_low; | ||
240 | } | ||
241 | } | ||
242 | else { | ||
243 | if (pci_mem_top < space) { | ||
244 | puts("Out of PCI Mem space\n"); | ||
245 | } | ||
246 | else { | ||
247 | pci_mem_top -= space; | ||
248 | pm->pci_addrs[j] = pci_mem_top; | ||
249 | } | ||
250 | } | ||
251 | pm->pci_command |= PCI_COMMAND_MEMORY; | ||
252 | } | ||
253 | } | ||
254 | } | ||
255 | addr_mask >>= 1; | ||
256 | addr_mask |= 0x80000000; | ||
257 | } while (addr_mask != 0xfffffffe); | ||
258 | |||
259 | /* Now, run the list one more time and map everything. | ||
260 | */ | ||
261 | for (i=0; i<pci_dev_cnt; i++) { | ||
262 | pm = &pci_map[i]; | ||
263 | for (j=0; j<6; j++) { | ||
264 | qs_pci_write_config_dword(pm->pci_bus, pm->pci_devfn, | ||
265 | PCI_BASE_ADDRESS_0 + (j * 4), pm->pci_addrs[j]); | ||
266 | } | ||
267 | |||
268 | /* Enable memory or address mapping. | ||
269 | */ | ||
270 | qs_pci_write_config_word(pm->pci_bus, pm->pci_devfn, PCI_COMMAND, | ||
271 | pm->pci_command); | ||
272 | } | ||
273 | } | ||
274 | |||
diff --git a/arch/ppc/boot/simple/pibs.c b/arch/ppc/boot/simple/pibs.c new file mode 100644 index 000000000000..1348740e503f --- /dev/null +++ b/arch/ppc/boot/simple/pibs.c | |||
@@ -0,0 +1,103 @@ | |||
1 | /* | ||
2 | * 2004-2005 (c) MontaVista, Software, Inc. This file is licensed under | ||
3 | * the terms of the GNU General Public License version 2. This program | ||
4 | * is licensed "as is" without any warranty of any kind, whether express | ||
5 | * or implied. | ||
6 | */ | ||
7 | |||
8 | #include <linux/types.h> | ||
9 | #include <linux/config.h> | ||
10 | #include <linux/string.h> | ||
11 | #include <linux/ctype.h> | ||
12 | #include <asm/ppcboot.h> | ||
13 | #include <asm/ibm4xx.h> | ||
14 | |||
15 | extern unsigned long decompress_kernel(unsigned long load_addr, int num_words, | ||
16 | unsigned long cksum); | ||
17 | |||
18 | /* We need to make sure that this is before the images to ensure | ||
19 | * that it's in a mapped location. - Tom */ | ||
20 | bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot"))); | ||
21 | bd_t *hold_residual = &hold_resid_buf; | ||
22 | |||
23 | /* String functions lifted from lib/vsprintf.c and lib/ctype.c */ | ||
24 | unsigned char _ctype[] = { | ||
25 | _C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ | ||
26 | _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ | ||
27 | _C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ | ||
28 | _C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ | ||
29 | _S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ | ||
30 | _P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ | ||
31 | _D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ | ||
32 | _D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ | ||
33 | _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ | ||
34 | _U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ | ||
35 | _U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ | ||
36 | _U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ | ||
37 | _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ | ||
38 | _L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ | ||
39 | _L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ | ||
40 | _L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ | ||
41 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ | ||
42 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ | ||
43 | _S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ | ||
44 | _P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ | ||
45 | _U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ | ||
46 | _U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ | ||
47 | _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ | ||
48 | _L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ | ||
49 | |||
50 | /** | ||
51 | * simple_strtoull - convert a string to an unsigned long long | ||
52 | * @cp: The start of the string | ||
53 | * @endp: A pointer to the end of the parsed string will be placed here | ||
54 | * @base: The number base to use | ||
55 | */ | ||
56 | unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base) | ||
57 | { | ||
58 | unsigned long long result = 0,value; | ||
59 | |||
60 | if (!base) { | ||
61 | base = 10; | ||
62 | if (*cp == '0') { | ||
63 | base = 8; | ||
64 | cp++; | ||
65 | if ((toupper(*cp) == 'X') && isxdigit(cp[1])) { | ||
66 | cp++; | ||
67 | base = 16; | ||
68 | } | ||
69 | } | ||
70 | } else if (base == 16) { | ||
71 | if (cp[0] == '0' && toupper(cp[1]) == 'X') | ||
72 | cp += 2; | ||
73 | } | ||
74 | while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp) | ||
75 | ? toupper(*cp) : *cp)-'A'+10) < base) { | ||
76 | result = result*base + value; | ||
77 | cp++; | ||
78 | } | ||
79 | if (endp) | ||
80 | *endp = (char *)cp; | ||
81 | return result; | ||
82 | } | ||
83 | |||
84 | void * | ||
85 | load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, | ||
86 | void *ign1, void *ign2) | ||
87 | { | ||
88 | unsigned long long mac64; | ||
89 | |||
90 | decompress_kernel(load_addr, num_words, cksum); | ||
91 | |||
92 | mac64 = simple_strtoull((char *)PIBS_MAC_BASE, 0, 16); | ||
93 | memcpy(hold_residual->bi_enetaddr, (char *)&mac64+2, 6); | ||
94 | #ifdef CONFIG_440GX | ||
95 | mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET), 0, 16); | ||
96 | memcpy(hold_residual->bi_enet1addr, (char *)&mac64+2, 6); | ||
97 | mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET*2), 0, 16); | ||
98 | memcpy(hold_residual->bi_enet2addr, (char *)&mac64+2, 6); | ||
99 | mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET*3), 0, 16); | ||
100 | memcpy(hold_residual->bi_enet3addr, (char *)&mac64+2, 6); | ||
101 | #endif | ||
102 | return (void *)hold_residual; | ||
103 | } | ||
diff --git a/arch/ppc/boot/simple/prepmap.c b/arch/ppc/boot/simple/prepmap.c new file mode 100644 index 000000000000..c871a4db6e8c --- /dev/null +++ b/arch/ppc/boot/simple/prepmap.c | |||
@@ -0,0 +1,12 @@ | |||
1 | /* | ||
2 | * 2004 (C) IBM. This file is licensed under the terms of the GNU General | ||
3 | * Public License version 2. This program is licensed "as is" without any | ||
4 | * warranty of any kind, whether express or implied. | ||
5 | */ | ||
6 | |||
7 | #include <nonstdio.h> | ||
8 | |||
9 | void board_isa_init(void) | ||
10 | { | ||
11 | ISA_init(0x80000000); | ||
12 | } | ||
diff --git a/arch/ppc/boot/simple/qspan_pci.c b/arch/ppc/boot/simple/qspan_pci.c new file mode 100644 index 000000000000..d2966d032a4c --- /dev/null +++ b/arch/ppc/boot/simple/qspan_pci.c | |||
@@ -0,0 +1,269 @@ | |||
1 | /* | ||
2 | * LinuxPPC arch/ppc/kernel/qspan_pci.c Dan Malek (dmalek@jlc.net) | ||
3 | * | ||
4 | * QSpan Motorola bus to PCI bridge. The config address register | ||
5 | * is located 0x500 from the base of the bridge control/status registers. | ||
6 | * The data register is located at 0x504. | ||
7 | * This is a two step operation. First, the address register is written, | ||
8 | * then the data register is read/written as required. | ||
9 | * I don't know what to do about interrupts (yet). | ||
10 | */ | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/pci.h> | ||
15 | #include <asm/mpc8xx.h> | ||
16 | |||
17 | /* | ||
18 | * When reading the configuration space, if something does not respond | ||
19 | * the bus times out and we get a machine check interrupt. So, the | ||
20 | * good ol' exception tables come to mind to trap it and return some | ||
21 | * value. | ||
22 | * | ||
23 | * On an error we just return a -1, since that is what the caller wants | ||
24 | * returned if nothing is present. I copied this from __get_user_asm, | ||
25 | * with the only difference of returning -1 instead of EFAULT. | ||
26 | * There is an associated hack in the machine check trap code. | ||
27 | * | ||
28 | * The QSPAN is also a big endian device, that is it makes the PCI | ||
29 | * look big endian to us. This presents a problem for the Linux PCI | ||
30 | * functions, which assume little endian. For example, we see the | ||
31 | * first 32-bit word like this: | ||
32 | * ------------------------ | ||
33 | * | Device ID | Vendor ID | | ||
34 | * ------------------------ | ||
35 | * If we read/write as a double word, that's OK. But in our world, | ||
36 | * when read as a word, device ID is at location 0, not location 2 as | ||
37 | * the little endian PCI would believe. We have to switch bits in | ||
38 | * the PCI addresses given to us to get the data to/from the correct | ||
39 | * byte lanes. | ||
40 | * | ||
41 | * The QSPAN only supports 4 bits of "slot" in the dev_fn instead of 5. | ||
42 | * It always forces the MS bit to zero. Therefore, dev_fn values | ||
43 | * greater than 128 are returned as "no device found" errors. | ||
44 | * | ||
45 | * The QSPAN can only perform long word (32-bit) configuration cycles. | ||
46 | * The "offset" must have the two LS bits set to zero. Read operations | ||
47 | * require we read the entire word and then sort out what should be | ||
48 | * returned. Write operations other than long word require that we | ||
49 | * read the long word, update the proper word or byte, then write the | ||
50 | * entire long word back. | ||
51 | * | ||
52 | * PCI Bridge hack. We assume (correctly) that bus 0 is the primary | ||
53 | * PCI bus from the QSPAN. If we are called with a bus number other | ||
54 | * than zero, we create a Type 1 configuration access that a downstream | ||
55 | * PCI bridge will interpret. | ||
56 | */ | ||
57 | |||
58 | #define __get_pci_config(x, addr, op) \ | ||
59 | __asm__ __volatile__( \ | ||
60 | "1: "op" %0,0(%1)\n" \ | ||
61 | " eieio\n" \ | ||
62 | "2:\n" \ | ||
63 | ".section .fixup,\"ax\"\n" \ | ||
64 | "3: li %0,-1\n" \ | ||
65 | " b 2b\n" \ | ||
66 | ".section __ex_table,\"a\"\n" \ | ||
67 | " .align 2\n" \ | ||
68 | " .long 1b,3b\n" \ | ||
69 | ".text" \ | ||
70 | : "=r"(x) : "r"(addr)) | ||
71 | |||
72 | #define QS_CONFIG_ADDR ((volatile uint *)(PCI_CSR_ADDR + 0x500)) | ||
73 | #define QS_CONFIG_DATA ((volatile uint *)(PCI_CSR_ADDR + 0x504)) | ||
74 | |||
75 | #define mk_config_addr(bus, dev, offset) \ | ||
76 | (((bus)<<16) | ((dev)<<8) | (offset & 0xfc)) | ||
77 | |||
78 | #define mk_config_type1(bus, dev, offset) \ | ||
79 | mk_config_addr(bus, dev, offset) | 1; | ||
80 | |||
81 | /* Initialize the QSpan device registers after power up. | ||
82 | */ | ||
83 | void | ||
84 | qspan_init(void) | ||
85 | { | ||
86 | uint *qptr; | ||
87 | |||
88 | |||
89 | |||
90 | qptr = (uint *)PCI_CSR_ADDR; | ||
91 | |||
92 | /* PCI Configuration/status. Upper bits written to clear | ||
93 | * pending interrupt or status. Lower bits enable QSPAN as | ||
94 | * PCI master, enable memory and I/O cycles, and enable PCI | ||
95 | * parity error checking. | ||
96 | * IMPORTANT: The last two bits of this word enable PCI | ||
97 | * master cycles into the QBus. The QSpan is broken and can't | ||
98 | * meet the timing specs of the PQ bus for this to work. Therefore, | ||
99 | * if you don't have external bus arbitration, you can't use | ||
100 | * this function. | ||
101 | */ | ||
102 | #ifdef EXTERNAL_PQ_ARB | ||
103 | qptr[1] = 0xf9000147; | ||
104 | #else | ||
105 | qptr[1] = 0xf9000144; | ||
106 | #endif | ||
107 | |||
108 | /* PCI Misc configuration. Set PCI latency timer resolution | ||
109 | * of 8 cycles, set cache size to 4 x 32. | ||
110 | */ | ||
111 | qptr[3] = 0; | ||
112 | |||
113 | /* Set up PCI Target address mapping. Enable, Posted writes, | ||
114 | * 2Gbyte space (processor memory controller determines actual size). | ||
115 | */ | ||
116 | qptr[64] = 0x8f000080; | ||
117 | |||
118 | /* Map processor 0x80000000 to PCI 0x00000000. | ||
119 | * Processor address bit 1 determines I/O type access (0x80000000) | ||
120 | * or memory type access (0xc0000000). | ||
121 | */ | ||
122 | qptr[65] = 0x80000000; | ||
123 | |||
124 | /* Enable error logging and clear any pending error status. | ||
125 | */ | ||
126 | qptr[80] = 0x90000000; | ||
127 | |||
128 | qptr[512] = 0x000c0003; | ||
129 | |||
130 | /* Set up Qbus slave image. | ||
131 | */ | ||
132 | qptr[960] = 0x01000000; | ||
133 | qptr[961] = 0x000000d1; | ||
134 | qptr[964] = 0x00000000; | ||
135 | qptr[965] = 0x000000d1; | ||
136 | |||
137 | } | ||
138 | |||
139 | /* Functions to support PCI bios-like features to read/write configuration | ||
140 | * space. If the function fails for any reason, a -1 (0xffffffff) value | ||
141 | * must be returned. | ||
142 | */ | ||
143 | #define DEVICE_NOT_FOUND (-1) | ||
144 | #define SUCCESSFUL 0 | ||
145 | |||
146 | int qs_pci_read_config_byte(unsigned char bus, unsigned char dev_fn, | ||
147 | unsigned char offset, unsigned char *val) | ||
148 | { | ||
149 | uint temp; | ||
150 | u_char *cp; | ||
151 | |||
152 | if ((bus > 7) || (dev_fn > 127)) { | ||
153 | *val = 0xff; | ||
154 | return DEVICE_NOT_FOUND; | ||
155 | } | ||
156 | |||
157 | if (bus == 0) | ||
158 | *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); | ||
159 | else | ||
160 | *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); | ||
161 | __get_pci_config(temp, QS_CONFIG_DATA, "lwz"); | ||
162 | |||
163 | offset ^= 0x03; | ||
164 | cp = ((u_char *)&temp) + (offset & 0x03); | ||
165 | *val = *cp; | ||
166 | return SUCCESSFUL; | ||
167 | } | ||
168 | |||
169 | int qs_pci_read_config_word(unsigned char bus, unsigned char dev_fn, | ||
170 | unsigned char offset, unsigned short *val) | ||
171 | { | ||
172 | uint temp; | ||
173 | ushort *sp; | ||
174 | |||
175 | if ((bus > 7) || (dev_fn > 127)) { | ||
176 | *val = 0xffff; | ||
177 | return DEVICE_NOT_FOUND; | ||
178 | } | ||
179 | |||
180 | if (bus == 0) | ||
181 | *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); | ||
182 | else | ||
183 | *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); | ||
184 | __get_pci_config(temp, QS_CONFIG_DATA, "lwz"); | ||
185 | offset ^= 0x02; | ||
186 | |||
187 | sp = ((ushort *)&temp) + ((offset >> 1) & 1); | ||
188 | *val = *sp; | ||
189 | return SUCCESSFUL; | ||
190 | } | ||
191 | |||
192 | int qs_pci_read_config_dword(unsigned char bus, unsigned char dev_fn, | ||
193 | unsigned char offset, unsigned int *val) | ||
194 | { | ||
195 | if ((bus > 7) || (dev_fn > 127)) { | ||
196 | *val = 0xffffffff; | ||
197 | return DEVICE_NOT_FOUND; | ||
198 | } | ||
199 | if (bus == 0) | ||
200 | *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); | ||
201 | else | ||
202 | *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); | ||
203 | __get_pci_config(*val, QS_CONFIG_DATA, "lwz"); | ||
204 | return SUCCESSFUL; | ||
205 | } | ||
206 | |||
207 | int qs_pci_write_config_byte(unsigned char bus, unsigned char dev_fn, | ||
208 | unsigned char offset, unsigned char val) | ||
209 | { | ||
210 | uint temp; | ||
211 | u_char *cp; | ||
212 | |||
213 | if ((bus > 7) || (dev_fn > 127)) | ||
214 | return DEVICE_NOT_FOUND; | ||
215 | |||
216 | qs_pci_read_config_dword(bus, dev_fn, offset, &temp); | ||
217 | |||
218 | offset ^= 0x03; | ||
219 | cp = ((u_char *)&temp) + (offset & 0x03); | ||
220 | *cp = val; | ||
221 | |||
222 | if (bus == 0) | ||
223 | *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); | ||
224 | else | ||
225 | *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); | ||
226 | *QS_CONFIG_DATA = temp; | ||
227 | |||
228 | return SUCCESSFUL; | ||
229 | } | ||
230 | |||
231 | int qs_pci_write_config_word(unsigned char bus, unsigned char dev_fn, | ||
232 | unsigned char offset, unsigned short val) | ||
233 | { | ||
234 | uint temp; | ||
235 | ushort *sp; | ||
236 | |||
237 | if ((bus > 7) || (dev_fn > 127)) | ||
238 | return DEVICE_NOT_FOUND; | ||
239 | |||
240 | qs_pci_read_config_dword(bus, dev_fn, offset, &temp); | ||
241 | |||
242 | offset ^= 0x02; | ||
243 | sp = ((ushort *)&temp) + ((offset >> 1) & 1); | ||
244 | *sp = val; | ||
245 | |||
246 | if (bus == 0) | ||
247 | *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); | ||
248 | else | ||
249 | *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); | ||
250 | *QS_CONFIG_DATA = temp; | ||
251 | |||
252 | return SUCCESSFUL; | ||
253 | } | ||
254 | |||
255 | int qs_pci_write_config_dword(unsigned char bus, unsigned char dev_fn, | ||
256 | unsigned char offset, unsigned int val) | ||
257 | { | ||
258 | if ((bus > 7) || (dev_fn > 127)) | ||
259 | return DEVICE_NOT_FOUND; | ||
260 | |||
261 | if (bus == 0) | ||
262 | *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); | ||
263 | else | ||
264 | *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); | ||
265 | *(unsigned int *)QS_CONFIG_DATA = val; | ||
266 | |||
267 | return SUCCESSFUL; | ||
268 | } | ||
269 | |||
diff --git a/arch/ppc/boot/simple/relocate.S b/arch/ppc/boot/simple/relocate.S new file mode 100644 index 000000000000..555a216ccc49 --- /dev/null +++ b/arch/ppc/boot/simple/relocate.S | |||
@@ -0,0 +1,216 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/relocate.S | ||
3 | * | ||
4 | * This is the common part of the loader relocation and initialization | ||
5 | * process. All of the board/processor specific initialization is | ||
6 | * done before we get here. | ||
7 | * | ||
8 | * Author: Tom Rini | ||
9 | * trini@mvista.com | ||
10 | * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others). | ||
11 | * | ||
12 | * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under | ||
13 | * the terms of the GNU General Public License version 2. This program | ||
14 | * is licensed "as is" without any warranty of any kind, whether express | ||
15 | * or implied. | ||
16 | */ | ||
17 | |||
18 | #include <linux/config.h> | ||
19 | #include <asm/cache.h> | ||
20 | #include <asm/ppc_asm.h> | ||
21 | |||
22 | #define GETSYM(reg, sym) \ | ||
23 | lis reg, sym@h; ori reg, reg, sym@l | ||
24 | |||
25 | .text | ||
26 | /* We get called from the early initialization code. | ||
27 | * Register 3 has the address where we were loaded, | ||
28 | * Register 4 contains any residual data passed from the | ||
29 | * boot rom. | ||
30 | */ | ||
31 | .globl relocate | ||
32 | relocate: | ||
33 | /* Save r3, r4 for later. | ||
34 | * The r8/r11 are legacy registers so I don't have to | ||
35 | * rewrite the code below :-). | ||
36 | */ | ||
37 | mr r8, r3 | ||
38 | mr r11, r4 | ||
39 | |||
40 | /* compute the size of the whole image in words. */ | ||
41 | GETSYM(r4,start) | ||
42 | GETSYM(r5,end) | ||
43 | |||
44 | addi r5,r5,3 /* round up */ | ||
45 | sub r5,r5,r4 /* end - start */ | ||
46 | srwi r5,r5,2 | ||
47 | mr r7,r5 /* Save for later use. */ | ||
48 | |||
49 | /* | ||
50 | * Check if we need to relocate ourselves to the link addr or were | ||
51 | * we loaded there to begin with. | ||
52 | */ | ||
53 | cmpw cr0,r3,r4 | ||
54 | beq start_ldr /* If 0, we don't need to relocate */ | ||
55 | |||
56 | /* Move this code somewhere safe. This is max(load + size, end) | ||
57 | * r8 == load address | ||
58 | */ | ||
59 | GETSYM(r4, start) | ||
60 | GETSYM(r5, end) | ||
61 | |||
62 | sub r6,r5,r4 | ||
63 | add r6,r8,r6 /* r6 == phys(load + size) */ | ||
64 | |||
65 | cmpw r5,r6 | ||
66 | bgt 1f | ||
67 | b 2f | ||
68 | 1: | ||
69 | mr r6, r5 | ||
70 | 2: | ||
71 | /* dest is in r6 */ | ||
72 | /* Ensure alignment --- this code is precautionary */ | ||
73 | addi r6,r6,4 | ||
74 | li r5,0x0003 | ||
75 | andc r6,r6,r5 | ||
76 | |||
77 | /* Find physical address and size of do_relocate */ | ||
78 | GETSYM(r5, __relocate_start) | ||
79 | GETSYM(r4, __relocate_end) | ||
80 | GETSYM(r3, start) | ||
81 | |||
82 | /* Size to copy */ | ||
83 | sub r4,r4,r5 | ||
84 | srwi r4,r4,2 | ||
85 | |||
86 | /* Src addr to copy (= __relocate_start - start + where_loaded) */ | ||
87 | sub r3,r5,r3 | ||
88 | add r5,r8,r3 | ||
89 | |||
90 | /* Save dest */ | ||
91 | mr r3, r6 | ||
92 | |||
93 | /* Do the copy */ | ||
94 | mtctr r4 | ||
95 | 3: lwz r4,0(r5) | ||
96 | stw r4,0(r3) | ||
97 | addi r3,r3,4 | ||
98 | addi r5,r5,4 | ||
99 | bdnz 3b | ||
100 | |||
101 | GETSYM(r4, __relocate_start) | ||
102 | GETSYM(r5, do_relocate) | ||
103 | |||
104 | sub r4,r5,r4 /* Get entry point for do_relocate in */ | ||
105 | add r6,r6,r4 /* relocated section */ | ||
106 | |||
107 | /* This will return to the relocated do_relocate */ | ||
108 | mtlr r6 | ||
109 | b flush_instruction_cache | ||
110 | |||
111 | .section ".relocate_code","xa" | ||
112 | |||
113 | do_relocate: | ||
114 | /* We have 2 cases --- start < load, or start > load | ||
115 | * This determines whether we copy from the end, or the start. | ||
116 | * Its easier to have 2 loops than to have paramaterised | ||
117 | * loops. Sigh. | ||
118 | */ | ||
119 | li r6,0 /* Clear checksum */ | ||
120 | mtctr r7 /* Setup for a loop */ | ||
121 | |||
122 | GETSYM(r4, start) | ||
123 | mr r3,r8 /* Get the load addr */ | ||
124 | |||
125 | cmpw cr0,r4,r3 /* If we need to copy from the end, do so */ | ||
126 | bgt do_relocate_from_end | ||
127 | |||
128 | do_relocate_from_start: | ||
129 | 1: lwz r5,0(r3) /* Load and decrement */ | ||
130 | stw r5,0(r4) /* Store and decrement */ | ||
131 | addi r3,r3,4 | ||
132 | addi r4,r4,4 | ||
133 | xor r6,r6,r5 /* Update checksum */ | ||
134 | bdnz 1b /* Are we done? */ | ||
135 | b do_relocate_out /* Finished */ | ||
136 | |||
137 | do_relocate_from_end: | ||
138 | GETSYM(r3, end) | ||
139 | slwi r4,r7,2 | ||
140 | add r4,r8,r4 /* Get the physical end */ | ||
141 | 1: lwzu r5,-4(r4) | ||
142 | stwu r5, -4(r3) | ||
143 | xor r6,r6,r5 | ||
144 | bdnz 1b | ||
145 | |||
146 | do_relocate_out: | ||
147 | GETSYM(r3,start_ldr) | ||
148 | mtlr r3 /* Easiest way to do an absolute jump */ | ||
149 | /* Some boards don't boot up with the I-cache enabled. Do that | ||
150 | * now because the decompress runs much faster that way. | ||
151 | * As a side effect, we have to ensure the data cache is not enabled | ||
152 | * so we can access the serial I/O without trouble. | ||
153 | */ | ||
154 | b flush_instruction_cache | ||
155 | |||
156 | .previous | ||
157 | |||
158 | start_ldr: | ||
159 | /* Clear all of BSS and set up stack for C calls */ | ||
160 | lis r3,edata@h | ||
161 | ori r3,r3,edata@l | ||
162 | lis r4,end@h | ||
163 | ori r4,r4,end@l | ||
164 | subi r3,r3,4 | ||
165 | subi r4,r4,4 | ||
166 | li r0,0 | ||
167 | 50: stwu r0,4(r3) | ||
168 | cmpw cr0,r3,r4 | ||
169 | bne 50b | ||
170 | 90: mr r9,r1 /* Save old stack pointer (in case it matters) */ | ||
171 | lis r1,.stack@h | ||
172 | ori r1,r1,.stack@l | ||
173 | addi r1,r1,4096*2 | ||
174 | subi r1,r1,256 | ||
175 | li r2,0x000F /* Mask pointer to 16-byte boundary */ | ||
176 | andc r1,r1,r2 | ||
177 | |||
178 | /* | ||
179 | * Exec kernel loader | ||
180 | */ | ||
181 | mr r3,r8 /* Load point */ | ||
182 | mr r4,r7 /* Program length */ | ||
183 | mr r5,r6 /* Checksum */ | ||
184 | mr r6,r11 /* Residual data */ | ||
185 | mr r7,r25 /* Validated OFW interface */ | ||
186 | bl load_kernel | ||
187 | |||
188 | /* | ||
189 | * Make sure the kernel knows we don't have things set in | ||
190 | * registers. -- Tom | ||
191 | */ | ||
192 | li r4,0 | ||
193 | li r5,0 | ||
194 | li r6,0 | ||
195 | |||
196 | /* | ||
197 | * Start at the begining. | ||
198 | */ | ||
199 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
200 | li r9,0xc | ||
201 | mtlr r9 | ||
202 | /* tell kernel we're prep, by putting 0xdeadc0de at KERNELLOAD, | ||
203 | * and tell the kernel to start on the 4th instruction since we | ||
204 | * overwrite the first 3 sometimes (which are 'nop'). | ||
205 | */ | ||
206 | lis r10,0xdeadc0de@h | ||
207 | ori r10,r10,0xdeadc0de@l | ||
208 | li r9,0 | ||
209 | stw r10,0(r9) | ||
210 | #else | ||
211 | li r9,0 | ||
212 | mtlr r9 | ||
213 | #endif | ||
214 | blr | ||
215 | |||
216 | .comm .stack,4096*2,4 | ||
diff --git a/arch/ppc/boot/simple/rw4/ppc_40x.h b/arch/ppc/boot/simple/rw4/ppc_40x.h new file mode 100644 index 000000000000..561fb26f5a93 --- /dev/null +++ b/arch/ppc/boot/simple/rw4/ppc_40x.h | |||
@@ -0,0 +1,664 @@ | |||
1 | /*----------------------------------------------------------------------------+ | ||
2 | | This source code has been made available to you by IBM on an AS-IS | ||
3 | | basis. Anyone receiving this source is licensed under IBM | ||
4 | | copyrights to use it in any way he or she deems fit, including | ||
5 | | copying it, modifying it, compiling it, and redistributing it either | ||
6 | | with or without modifications. No license under IBM patents or | ||
7 | | patent applications is to be implied by the copyright license. | ||
8 | | | ||
9 | | Any user of this software should understand that IBM cannot provide | ||
10 | | technical support for this software and will not be responsible for | ||
11 | | any consequences resulting from the use of this software. | ||
12 | | | ||
13 | | Any person who transfers this source code or any derivative work | ||
14 | | must include the IBM copyright notice, this paragraph, and the | ||
15 | | preceding two paragraphs in the transferred software. | ||
16 | | | ||
17 | | COPYRIGHT I B M CORPORATION 1997 | ||
18 | | LICENSED MATERIAL - PROGRAM PROPERTY OF I B M | ||
19 | +----------------------------------------------------------------------------*/ | ||
20 | /*----------------------------------------------------------------------------+ | ||
21 | | Author: Tony J. Cerreto | ||
22 | | Component: Assembler include file. | ||
23 | | File: ppc_40x.h | ||
24 | | Purpose: Include file containing PPC DCR defines. | ||
25 | | | ||
26 | | Changes: | ||
27 | | Date Author Comment | ||
28 | | --------- ------ -------------------------------------------------------- | ||
29 | | 01-Mar-00 tjc Created | ||
30 | +----------------------------------------------------------------------------*/ | ||
31 | /* added by linguohui*/ | ||
32 | #define MW | ||
33 | /*----------------------------------------------------------------------------+ | ||
34 | | PPC Special purpose registers Numbers | ||
35 | +----------------------------------------------------------------------------*/ | ||
36 | #define ccr0 0x3b3 /* core configuration reg */ | ||
37 | #define ctr 0x009 /* count register */ | ||
38 | #define ctrreg 0x009 /* count register */ | ||
39 | #define dbcr0 0x3f2 /* debug control register 0 */ | ||
40 | #define dbcr1 0x3bd /* debug control register 1 */ | ||
41 | #define dbsr 0x3f0 /* debug status register */ | ||
42 | #define dccr 0x3fa /* data cache control reg. */ | ||
43 | #define dcwr 0x3ba /* data cache write-thru reg */ | ||
44 | #define dear 0x3d5 /* data exception address reg */ | ||
45 | #define esr 0x3d4 /* exception syndrome register */ | ||
46 | #define evpr 0x3d6 /* exception vector prefix reg */ | ||
47 | #define iccr 0x3fb /* instruction cache cntrl re */ | ||
48 | #define icdbdr 0x3d3 /* instr cache dbug data reg */ | ||
49 | #define lrreg 0x008 /* link register */ | ||
50 | #define pid 0x3b1 /* process id reg */ | ||
51 | #define pit 0x3db /* programmable interval time */ | ||
52 | #define pvr 0x11f /* processor version register */ | ||
53 | #define sgr 0x3b9 /* storage guarded reg */ | ||
54 | #define sler 0x3bb /* storage little endian reg */ | ||
55 | #define sprg0 0x110 /* special general purpose 0 */ | ||
56 | #define sprg1 0x111 /* special general purpose 1 */ | ||
57 | #define sprg2 0x112 /* special general purpose 2 */ | ||
58 | #define sprg3 0x113 /* special general purpose 3 */ | ||
59 | #define sprg4 0x114 /* special general purpose 4 */ | ||
60 | #define sprg5 0x115 /* special general purpose 5 */ | ||
61 | #define sprg6 0x116 /* special general purpose 6 */ | ||
62 | #define sprg7 0x117 /* special general purpose 7 */ | ||
63 | #define srr0 0x01a /* save/restore register 0 */ | ||
64 | #define srr1 0x01b /* save/restore register 1 */ | ||
65 | #define srr2 0x3de /* save/restore register 2 */ | ||
66 | #define srr3 0x3df /* save/restore register 3 */ | ||
67 | #define tbhi 0x11D | ||
68 | #define tblo 0x11C | ||
69 | #define tcr 0x3da /* timer control register */ | ||
70 | #define tsr 0x3d8 /* timer status register */ | ||
71 | #define xerreg 0x001 /* fixed point exception */ | ||
72 | #define xer 0x001 /* fixed point exception */ | ||
73 | #define zpr 0x3b0 /* zone protection reg */ | ||
74 | |||
75 | /*----------------------------------------------------------------------------+ | ||
76 | | Decompression Controller | ||
77 | +----------------------------------------------------------------------------*/ | ||
78 | #define kiar 0x014 /* Decompression cntl addr reg */ | ||
79 | #define kidr 0x015 /* Decompression cntl data reg */ | ||
80 | #define kitor0 0x00 /* index table origin Reg 0 */ | ||
81 | #define kitor1 0x01 /* index table origin Reg 1 */ | ||
82 | #define kitor2 0x02 /* index table origin Reg 2 */ | ||
83 | #define kitor3 0x03 /* index table origin Reg 3 */ | ||
84 | #define kaddr0 0x04 /* addr decode Definition Reg 0 */ | ||
85 | #define kaddr1 0x05 /* addr decode Definition Reg 1 */ | ||
86 | #define kconf 0x40 /* Decompression cntl config reg */ | ||
87 | #define kid 0x41 /* Decompression cntl id reg */ | ||
88 | #define kver 0x42 /* Decompression cntl ver number */ | ||
89 | #define kpear 0x50 /* bus error addr reg (PLB) */ | ||
90 | #define kbear 0x51 /* bus error addr reg (DCP-EBC) */ | ||
91 | #define kesr0 0x52 /* bus error status reg 0 */ | ||
92 | |||
93 | /*----------------------------------------------------------------------------+ | ||
94 | | Romeo Specific Device Control Register Numbers. | ||
95 | +----------------------------------------------------------------------------*/ | ||
96 | #ifndef VESTA | ||
97 | #define cdbcr 0x3d7 /* cache debug cntrl reg */ | ||
98 | |||
99 | #define a_latcnt 0x1a9 /* PLB Latency count */ | ||
100 | #define a_tgval 0x1ac /* tone generation value */ | ||
101 | #define a_plb_pr 0x1bf /* PLB priority */ | ||
102 | |||
103 | #define cic_sel1 0x031 /* select register 1 */ | ||
104 | #define cic_sel2 0x032 /* select register 2 */ | ||
105 | |||
106 | #define clkgcrst 0x122 /* chip reset register */ | ||
107 | |||
108 | #define cp_cpmsr 0x100 /*rstatus register */ | ||
109 | #define cp_cpmer 0x101 /* enable register */ | ||
110 | |||
111 | #define dcp_kiar 0x190 /* indirect address register */ | ||
112 | #define dcp_kidr 0x191 /* indirect data register */ | ||
113 | |||
114 | #define hsmc_mcgr 0x1c0 /* HSMC global register */ | ||
115 | #define hsmc_mcbesr 0x1c1 /* bus error status register */ | ||
116 | #define hsmc_mcbear 0x1c2 /* bus error address register*/ | ||
117 | #define hsmc_mcbr0 0x1c4 /* SDRAM sub-ctrl bank reg 0 */ | ||
118 | #define hsmc_mccr0 0x1c5 /* SDRAM sub-ctrl ctrl reg 0 */ | ||
119 | #define hsmc_mcbr1 0x1c7 /* SDRAM sub-ctrl bank reg 1 */ | ||
120 | #define hsmc_mccr1 0x1c8 /* SDRAM sub-ctrl ctrl reg 1 */ | ||
121 | #define hsmc_sysr 0x1d1 /* system register */ | ||
122 | #define hsmc_data 0x1d2 /* data register */ | ||
123 | #define hsmc_mccrr 0x1d3 /* refresh register */ | ||
124 | |||
125 | #define ocm_pbar 0x1E0 /* base address register */ | ||
126 | |||
127 | #define plb0_pacr0 0x057 /* PLB arbiter control reg */ | ||
128 | #define plb1_pacr1 0x067 /* PLB arbiter control reg */ | ||
129 | |||
130 | #define v_displb 0x157 /* set left border of display*/ | ||
131 | #define v_disptb 0x158 /* top border of display */ | ||
132 | #define v_osd_la 0x159 /* first link address for OSD*/ | ||
133 | #define v_ptsdlta 0x15E /* PTS delta register */ | ||
134 | #define v_v0base 0x16C /* base mem add for VBI-0 */ | ||
135 | #define v_v1base 0x16D /* base mem add for VBI-1 */ | ||
136 | #define v_osbase 0x16E /* base mem add for OSD data */ | ||
137 | #endif | ||
138 | |||
139 | /*----------------------------------------------------------------------------+ | ||
140 | | Vesta Device Control Register Numbers. | ||
141 | +----------------------------------------------------------------------------*/ | ||
142 | /*----------------------------------------------------------------------------+ | ||
143 | | Cross bar switch. | ||
144 | +----------------------------------------------------------------------------*/ | ||
145 | #define cbs0_cr 0x010 /* CBS configuration register */ | ||
146 | |||
147 | /*----------------------------------------------------------------------------+ | ||
148 | | DCR external master (DCRX). | ||
149 | +----------------------------------------------------------------------------*/ | ||
150 | #define dcrx0_icr 0x020 /* internal control register */ | ||
151 | #define dcrx0_isr 0x021 /* internal status register */ | ||
152 | #define dcrx0_ecr 0x022 /* external control register */ | ||
153 | #define dcrx0_esr 0x023 /* external status register */ | ||
154 | #define dcrx0_tar 0x024 /* target address register */ | ||
155 | #define dcrx0_tdr 0x025 /* target data register */ | ||
156 | #define dcrx0_igr 0x026 /* interrupt generation register */ | ||
157 | #define dcrx0_bcr 0x027 /* buffer control register */ | ||
158 | |||
159 | /*----------------------------------------------------------------------------+ | ||
160 | | Chip interconnect configuration. | ||
161 | +----------------------------------------------------------------------------*/ | ||
162 | #define cic0_cr 0x030 /* CIC control register */ | ||
163 | #define cic0_vcr 0x033 /* video macro control reg */ | ||
164 | #define cic0_sel3 0x035 /* select register 3 */ | ||
165 | |||
166 | /*----------------------------------------------------------------------------+ | ||
167 | | Chip interconnect configuration. | ||
168 | +----------------------------------------------------------------------------*/ | ||
169 | #define sgpo0_sgpO 0x036 /* simplified GPIO output */ | ||
170 | #define sgpo0_gpod 0x037 /* simplified GPIO open drain */ | ||
171 | #define sgpo0_gptc 0x038 /* simplified GPIO tristate cntl */ | ||
172 | #define sgpo0_gpi 0x039 /* simplified GPIO input */ | ||
173 | |||
174 | /*----------------------------------------------------------------------------+ | ||
175 | | Universal interrupt controller. | ||
176 | +----------------------------------------------------------------------------*/ | ||
177 | #define uic0_sr 0x040 /* status register */ | ||
178 | #define uic0_srs 0x041 /* status register set */ | ||
179 | #define uic0_er 0x042 /* enable register */ | ||
180 | #define uic0_cr 0x043 /* critical register */ | ||
181 | #define uic0_pr 0x044 /* parity register */ | ||
182 | #define uic0_tr 0x045 /* triggering register */ | ||
183 | #define uic0_msr 0x046 /* masked status register */ | ||
184 | #define uic0_vr 0x047 /* vector register */ | ||
185 | #define uic0_vcr 0x048 /* enable config register */ | ||
186 | |||
187 | /*----------------------------------------------------------------------------+ | ||
188 | | PLB 0 and 1. | ||
189 | +----------------------------------------------------------------------------*/ | ||
190 | #define pb0_pesr 0x054 /* PLB error status reg 0 */ | ||
191 | #define pb0_pesrs 0x055 /* PLB error status reg 0 set */ | ||
192 | #define pb0_pear 0x056 /* PLB error address reg */ | ||
193 | |||
194 | #define pb1_pesr 0x064 /* PLB error status reg 1 */ | ||
195 | #define pb1_pesrs 0x065 /* PLB error status reg 1 set */ | ||
196 | #define pb1_pear 0x066 /* PLB error address reg */ | ||
197 | |||
198 | /*----------------------------------------------------------------------------+ | ||
199 | | EBIU DCR registers. | ||
200 | +----------------------------------------------------------------------------*/ | ||
201 | #define ebiu0_brcrh0 0x070 /* bus region register 0 high */ | ||
202 | #define ebiu0_brcrh1 0x071 /* bus region register 1 high */ | ||
203 | #define ebiu0_brcrh2 0x072 /* bus region register 2 high */ | ||
204 | #define ebiu0_brcrh3 0x073 /* bus region register 3 high */ | ||
205 | #define ebiu0_brcrh4 0x074 /* bus region register 4 high */ | ||
206 | #define ebiu0_brcrh5 0x075 /* bus region register 5 high */ | ||
207 | #define ebiu0_brcrh6 0x076 /* bus region register 6 high */ | ||
208 | #define ebiu0_brcrh7 0x077 /* bus region register 7 high */ | ||
209 | #define ebiu0_brcr0 0x080 /* bus region register 0 */ | ||
210 | #define ebiu0_brcr1 0x081 /* bus region register 1 */ | ||
211 | #define ebiu0_brcr2 0x082 /* bus region register 2 */ | ||
212 | #define ebiu0_brcr3 0x083 /* bus region register 3 */ | ||
213 | #define ebiu0_brcr4 0x084 /* bus region register 4 */ | ||
214 | #define ebiu0_brcr5 0x085 /* bus region register 5 */ | ||
215 | #define ebiu0_brcr6 0x086 /* bus region register 6 */ | ||
216 | #define ebiu0_brcr7 0x087 /* bus region register 7 */ | ||
217 | #define ebiu0_bear 0x090 /* bus error address register */ | ||
218 | #define ebiu0_besr 0x091 /* bus error syndrome reg */ | ||
219 | #define ebiu0_besr0s 0x093 /* bus error syndrome reg */ | ||
220 | #define ebiu0_biucr 0x09a /* bus interface control reg */ | ||
221 | |||
222 | /*----------------------------------------------------------------------------+ | ||
223 | | OPB bridge. | ||
224 | +----------------------------------------------------------------------------*/ | ||
225 | #define opbw0_gesr 0x0b0 /* error status reg */ | ||
226 | #define opbw0_gesrs 0x0b1 /* error status reg */ | ||
227 | #define opbw0_gear 0x0b2 /* error address reg */ | ||
228 | |||
229 | /*----------------------------------------------------------------------------+ | ||
230 | | DMA. | ||
231 | +----------------------------------------------------------------------------*/ | ||
232 | #define dma0_cr0 0x0c0 /* DMA channel control reg 0 */ | ||
233 | #define dma0_ct0 0x0c1 /* DMA count register 0 */ | ||
234 | #define dma0_da0 0x0c2 /* DMA destination addr reg 0 */ | ||
235 | #define dma0_sa0 0x0c3 /* DMA source addr register 0 */ | ||
236 | #define dma0_cc0 0x0c4 /* DMA chained count 0 */ | ||
237 | #define dma0_cr1 0x0c8 /* DMA channel control reg 1 */ | ||
238 | #define dma0_ct1 0x0c9 /* DMA count register 1 */ | ||
239 | #define dma0_da1 0x0ca /* DMA destination addr reg 1 */ | ||
240 | #define dma0_sa1 0x0cb /* DMA source addr register 1 */ | ||
241 | #define dma0_cc1 0x0cc /* DMA chained count 1 */ | ||
242 | #define dma0_cr2 0x0d0 /* DMA channel control reg 2 */ | ||
243 | #define dma0_ct2 0x0d1 /* DMA count register 2 */ | ||
244 | #define dma0_da2 0x0d2 /* DMA destination addr reg 2 */ | ||
245 | #define dma0_sa2 0x0d3 /* DMA source addr register 2 */ | ||
246 | #define dma0_cc2 0x0d4 /* DMA chained count 2 */ | ||
247 | #define dma0_cr3 0x0d8 /* DMA channel control reg 3 */ | ||
248 | #define dma0_ct3 0x0d9 /* DMA count register 3 */ | ||
249 | #define dma0_da3 0x0da /* DMA destination addr reg 3 */ | ||
250 | #define dma0_sa3 0x0db /* DMA source addr register 3 */ | ||
251 | #define dma0_cc3 0x0dc /* DMA chained count 3 */ | ||
252 | #define dma0_sr 0x0e0 /* DMA status register */ | ||
253 | #define dma0_srs 0x0e1 /* DMA status register */ | ||
254 | #define dma0_s1 0x031 /* DMA select1 register */ | ||
255 | #define dma0_s2 0x032 /* DMA select2 register */ | ||
256 | |||
257 | /*---------------------------------------------------------------------------+ | ||
258 | | Clock and power management. | ||
259 | +----------------------------------------------------------------------------*/ | ||
260 | #define cpm0_fr 0x102 /* force register */ | ||
261 | |||
262 | /*----------------------------------------------------------------------------+ | ||
263 | | Serial Clock Control. | ||
264 | +----------------------------------------------------------------------------*/ | ||
265 | #define ser0_ccr 0x120 /* serial clock control register */ | ||
266 | |||
267 | /*----------------------------------------------------------------------------+ | ||
268 | | Audio Clock Control. | ||
269 | +----------------------------------------------------------------------------*/ | ||
270 | #define aud0_apcr 0x121 /* audio clock ctrl register */ | ||
271 | |||
272 | /*----------------------------------------------------------------------------+ | ||
273 | | DENC. | ||
274 | +----------------------------------------------------------------------------*/ | ||
275 | #define denc0_idr 0x130 /* DENC ID register */ | ||
276 | #define denc0_cr1 0x131 /* control register 1 */ | ||
277 | #define denc0_rr1 0x132 /* microvision 1 (reserved 1) */ | ||
278 | #define denc0_cr2 0x133 /* control register 2 */ | ||
279 | #define denc0_rr2 0x134 /* microvision 2 (reserved 2) */ | ||
280 | #define denc0_rr3 0x135 /* microvision 3 (reserved 3) */ | ||
281 | #define denc0_rr4 0x136 /* microvision 4 (reserved 4) */ | ||
282 | #define denc0_rr5 0x137 /* microvision 5 (reserved 5) */ | ||
283 | #define denc0_ccdr 0x138 /* closed caption data */ | ||
284 | #define denc0_cccr 0x139 /* closed caption control */ | ||
285 | #define denc0_trr 0x13A /* teletext request register */ | ||
286 | #define denc0_tosr 0x13B /* teletext odd field line se */ | ||
287 | #define denc0_tesr 0x13C /* teletext even field line s */ | ||
288 | #define denc0_rlsr 0x13D /* RGB rhift left register */ | ||
289 | #define denc0_vlsr 0x13E /* video level shift register */ | ||
290 | #define denc0_vsr 0x13F /* video scaling register */ | ||
291 | |||
292 | /*----------------------------------------------------------------------------+ | ||
293 | | Video decoder. Suspect 0x179, 0x169, 0x16a, 0x152 (rc). | ||
294 | +----------------------------------------------------------------------------*/ | ||
295 | #define vid0_ccntl 0x140 /* control decoder operation */ | ||
296 | #define vid0_cmode 0x141 /* video operational mode */ | ||
297 | #define vid0_sstc0 0x142 /* STC high order bits 31:0 */ | ||
298 | #define vid0_sstc1 0x143 /* STC low order bit 32 */ | ||
299 | #define vid0_spts0 0x144 /* PTS high order bits 31:0 */ | ||
300 | #define vid0_spts1 0x145 /* PTS low order bit 32 */ | ||
301 | #define vid0_fifo 0x146 /* FIFO data port */ | ||
302 | #define vid0_fifos 0x147 /* FIFO status */ | ||
303 | #define vid0_cmd 0x148 /* send command to decoder */ | ||
304 | #define vid0_cmdd 0x149 /* port for command params */ | ||
305 | #define vid0_cmdst 0x14A /* command status */ | ||
306 | #define vid0_cmdad 0x14B /* command address */ | ||
307 | #define vid0_procia 0x14C /* instruction store */ | ||
308 | #define vid0_procid 0x14D /* data port for I_Store */ | ||
309 | #define vid0_osdm 0x151 /* OSD mode control */ | ||
310 | #define vid0_hosti 0x152 /* base interrupt register */ | ||
311 | #define vid0_mask 0x153 /* interrupt mask register */ | ||
312 | #define vid0_dispm 0x154 /* operational mode for Disp */ | ||
313 | #define vid0_dispd 0x155 /* setting for 'Sync' delay */ | ||
314 | #define vid0_vbctl 0x156 /* VBI */ | ||
315 | #define vid0_ttxctl 0x157 /* teletext control */ | ||
316 | #define vid0_disptb 0x158 /* display left/top border */ | ||
317 | #define vid0_osdgla 0x159 /* Graphics plane link addr */ | ||
318 | #define vid0_osdila 0x15A /* Image plane link addr */ | ||
319 | #define vid0_rbthr 0x15B /* rate buffer threshold */ | ||
320 | #define vid0_osdcla 0x15C /* Cursor link addr */ | ||
321 | #define vid0_stcca 0x15D /* STC common address */ | ||
322 | #define vid0_ptsctl 0x15F /* PTS Control */ | ||
323 | #define vid0_wprot 0x165 /* write protect for I_Store */ | ||
324 | #define vid0_vcqa 0x167 /* video clip queued block Ad */ | ||
325 | #define vid0_vcql 0x168 /* video clip queued block Le */ | ||
326 | #define vid0_blksz 0x169 /* block size bytes for copy op */ | ||
327 | #define vid0_srcad 0x16a /* copy source address bits 6-31 */ | ||
328 | #define vid0_udbas 0x16B /* base mem add for user data */ | ||
329 | #define vid0_vbibas 0x16C /* base mem add for VBI 0/1 */ | ||
330 | #define vid0_osdibas 0x16D /* Image plane base address */ | ||
331 | #define vid0_osdgbas 0x16E /* Graphic plane base address */ | ||
332 | #define vid0_rbbase 0x16F /* base mem add for video buf */ | ||
333 | #define vid0_dramad 0x170 /* DRAM address */ | ||
334 | #define vid0_dramdt 0x171 /* data port for DRAM access */ | ||
335 | #define vid0_dramcs 0x172 /* DRAM command and statusa */ | ||
336 | #define vid0_vcwa 0x173 /* v clip work address */ | ||
337 | #define vid0_vcwl 0x174 /* v clip work length */ | ||
338 | #define vid0_mseg0 0x175 /* segment address 0 */ | ||
339 | #define vid0_mseg1 0x176 /* segment address 1 */ | ||
340 | #define vid0_mseg2 0x177 /* segment address 2 */ | ||
341 | #define vid0_mseg3 0x178 /* segment address 3 */ | ||
342 | #define vid0_fbbase 0x179 /* frame buffer base memory */ | ||
343 | #define vid0_osdcbas 0x17A /* Cursor base addr */ | ||
344 | #define vid0_lboxtb 0x17B /* top left border */ | ||
345 | #define vid0_trdly 0x17C /* transparency gate delay */ | ||
346 | #define vid0_sbord 0x17D /* left/top small pict. bord. */ | ||
347 | #define vid0_zoffs 0x17E /* hor/ver zoom window */ | ||
348 | #define vid0_rbsz 0x17F /* rate buffer size read */ | ||
349 | |||
350 | /*----------------------------------------------------------------------------+ | ||
351 | | Transport demultiplexer. | ||
352 | +----------------------------------------------------------------------------*/ | ||
353 | #define xpt0_lr 0x180 /* demux location register */ | ||
354 | #define xpt0_data 0x181 /* demux data register */ | ||
355 | #define xpt0_ir 0x182 /* demux interrupt register */ | ||
356 | |||
357 | #define xpt0_config1 0x0000 /* configuration 1 */ | ||
358 | #define xpt0_control1 0x0001 /* control 1 */ | ||
359 | #define xpt0_festat 0x0002 /* Front-end status */ | ||
360 | #define xpt0_feimask 0x0003 /* Front_end interrupt Mask */ | ||
361 | #define xpt0_ocmcnfg 0x0004 /* OCM Address */ | ||
362 | #define xpt0_settapi 0x0005 /* Set TAP Interrupt */ | ||
363 | |||
364 | #define xpt0_pcrhi 0x0010 /* PCR High */ | ||
365 | #define xpt0_pcrlow 0x0011 /* PCR Low */ | ||
366 | #define xpt0_lstchi 0x0012 /* Latched STC High */ | ||
367 | #define xpt0_lstclow 0x0013 /* Latched STC Low */ | ||
368 | #define xpt0_stchi 0x0014 /* STC High */ | ||
369 | #define xpt0_stclow 0x0015 /* STC Low */ | ||
370 | #define xpt0_pwm 0x0016 /* PWM */ | ||
371 | #define xpt0_pcrstct 0x0017 /* PCR-STC Threshold */ | ||
372 | #define xpt0_pcrstcd 0x0018 /* PCR-STC Delta */ | ||
373 | #define xpt0_stccomp 0x0019 /* STC Compare */ | ||
374 | #define xpt0_stccmpd 0x001a /* STC Compare Disarm */ | ||
375 | |||
376 | #define xpt0_dsstat 0x0048 /* Descrambler Status */ | ||
377 | #define xpt0_dsimask 0x0049 /* Descrambler Interrupt Mask */ | ||
378 | |||
379 | #define xpt0_vcchng 0x01f0 /* Video Channel Change */ | ||
380 | #define xpt0_acchng 0x01f1 /* Audio Channel Change */ | ||
381 | #define xpt0_axenable 0x01fe /* Aux PID Enables */ | ||
382 | #define xpt0_pcrpid 0x01ff /* PCR PID */ | ||
383 | |||
384 | #define xpt0_config2 0x1000 /* Configuration 2 */ | ||
385 | #define xpt0_pbuflvl 0x1002 /* Packet Buffer Level */ | ||
386 | #define xpt0_intmask 0x1003 /* Interrupt Mask */ | ||
387 | #define xpt0_plbcnfg 0x1004 /* PLB Configuration */ | ||
388 | |||
389 | #define xpt0_qint 0x1010 /* Queues Interrupts */ | ||
390 | #define xpt0_qintmsk 0x1011 /* Queues Interrupts Mask */ | ||
391 | #define xpt0_astatus 0x1012 /* Audio Status */ | ||
392 | #define xpt0_aintmask 0x1013 /* Audio Interrupt Mask */ | ||
393 | #define xpt0_vstatus 0x1014 /* Video Status */ | ||
394 | #define xpt0_vintmask 0x1015 /* Video Interrupt Mask */ | ||
395 | |||
396 | #define xpt0_qbase 0x1020 /* Queue Base */ | ||
397 | #define xpt0_bucketq 0x1021 /* Bucket Queue */ | ||
398 | #define xpt0_qstops 0x1024 /* Queue Stops */ | ||
399 | #define xpt0_qresets 0x1025 /* Queue Resets */ | ||
400 | #define xpt0_sfchng 0x1026 /* Section Filter Change */ | ||
401 | |||
402 | /*----------------------------------------------------------------------------+ | ||
403 | | Audio decoder. Suspect 0x1ad, 0x1b4, 0x1a3, 0x1a5 (read/write status) | ||
404 | +----------------------------------------------------------------------------*/ | ||
405 | #define aud0_ctrl0 0x1a0 /* control 0 */ | ||
406 | #define aud0_ctrl1 0x1a1 /* control 1 */ | ||
407 | #define aud0_ctrl2 0x1a2 /* control 2 */ | ||
408 | #define aud0_cmd 0x1a3 /* command register */ | ||
409 | #define aud0_isr 0x1a4 /* interrupt status register */ | ||
410 | #define aud0_imr 0x1a5 /* interrupt mask register */ | ||
411 | #define aud0_dsr 0x1a6 /* decoder status register */ | ||
412 | #define aud0_stc 0x1a7 /* system time clock */ | ||
413 | #define aud0_csr 0x1a8 /* channel status register */ | ||
414 | #define aud0_lcnt 0x1a9 /* queued address register 2 */ | ||
415 | #define aud0_pts 0x1aa /* presentation time stamp */ | ||
416 | #define aud0_tgctrl 0x1ab /* tone generation control */ | ||
417 | #define aud0_qlr2 0x1ac /* queued length register 2 */ | ||
418 | #define aud0_auxd 0x1ad /* aux data */ | ||
419 | #define aud0_strmid 0x1ae /* stream ID */ | ||
420 | #define aud0_qar 0x1af /* queued address register */ | ||
421 | #define aud0_dsps 0x1b0 /* DSP status */ | ||
422 | #define aud0_qlr 0x1b1 /* queued len address */ | ||
423 | #define aud0_dspc 0x1b2 /* DSP control */ | ||
424 | #define aud0_wlr2 0x1b3 /* working length register 2 */ | ||
425 | #define aud0_instd 0x1b4 /* instruction download */ | ||
426 | #define aud0_war 0x1b5 /* working address register */ | ||
427 | #define aud0_seg1 0x1b6 /* segment 1 base register */ | ||
428 | #define aud0_seg2 0x1b7 /* segment 2 base register */ | ||
429 | #define aud0_avf 0x1b9 /* audio att value front */ | ||
430 | #define aud0_avr 0x1ba /* audio att value rear */ | ||
431 | #define aud0_avc 0x1bb /* audio att value center */ | ||
432 | #define aud0_seg3 0x1bc /* segment 3 base register */ | ||
433 | #define aud0_offset 0x1bd /* offset address */ | ||
434 | #define aud0_wrl 0x1be /* working length register */ | ||
435 | #define aud0_war2 0x1bf /* working address register 2 */ | ||
436 | |||
437 | /*----------------------------------------------------------------------------+ | ||
438 | | High speed memory controller 0 and 1. | ||
439 | +----------------------------------------------------------------------------*/ | ||
440 | #define hsmc0_gr 0x1e0 /* HSMC global register */ | ||
441 | #define hsmc0_besr 0x1e1 /* bus error status register */ | ||
442 | #define hsmc0_bear 0x1e2 /* bus error address register */ | ||
443 | #define hsmc0_br0 0x1e4 /* SDRAM sub-ctrl bank reg 0 */ | ||
444 | #define hsmc0_cr0 0x1e5 /* SDRAM sub-ctrl ctrl reg 0 */ | ||
445 | #define hsmc0_br1 0x1e7 /* SDRAM sub-ctrl bank reg 1 */ | ||
446 | #define hsmc0_cr1 0x1e8 /* SDRAM sub-ctrl ctrl reg 1 */ | ||
447 | #define hsmc0_sysr 0x1f1 /* system register */ | ||
448 | #define hsmc0_data 0x1f2 /* data register */ | ||
449 | #define hsmc0_crr 0x1f3 /* refresh register */ | ||
450 | |||
451 | #define hsmc1_gr 0x1c0 /* HSMC global register */ | ||
452 | #define hsmc1_besr 0x1c1 /* bus error status register */ | ||
453 | #define hsmc1_bear 0x1c2 /* bus error address register */ | ||
454 | #define hsmc1_br0 0x1c4 /* SDRAM sub-ctrl bank reg 0 */ | ||
455 | #define hsmc1_cr0 0x1c5 /* SDRAM sub-ctrl ctrl reg 0 */ | ||
456 | #define hsmc1_br1 0x1c7 /* SDRAM sub-ctrl bank reg 1 */ | ||
457 | #define hsmc1_cr1 0x1c8 /* SDRAM sub-ctrl ctrl reg 1 */ | ||
458 | #define hsmc1_sysr 0x1d1 /* system register */ | ||
459 | #define hsmc1_data 0x1d2 /* data register */ | ||
460 | #define hsmc1_crr 0x1d3 /* refresh register */ | ||
461 | |||
462 | /*----------------------------------------------------------------------------+ | ||
463 | | Machine State Register bit definitions. | ||
464 | +----------------------------------------------------------------------------*/ | ||
465 | #define msr_ape 0x00100000 | ||
466 | #define msr_apa 0x00080000 | ||
467 | #define msr_we 0x00040000 | ||
468 | #define msr_ce 0x00020000 | ||
469 | #define msr_ile 0x00010000 | ||
470 | #define msr_ee 0x00008000 | ||
471 | #define msr_pr 0x00004000 | ||
472 | #define msr_me 0x00001000 | ||
473 | #define msr_de 0x00000200 | ||
474 | #define msr_ir 0x00000020 | ||
475 | #define msr_dr 0x00000010 | ||
476 | #define msr_le 0x00000001 | ||
477 | |||
478 | /*----------------------------------------------------------------------------+ | ||
479 | | Used during interrupt processing. | ||
480 | +----------------------------------------------------------------------------*/ | ||
481 | #define stack_reg_image_size 160 | ||
482 | |||
483 | /*----------------------------------------------------------------------------+ | ||
484 | | Function prolog definition and other Metaware (EABI) defines. | ||
485 | +----------------------------------------------------------------------------*/ | ||
486 | #ifdef MW | ||
487 | |||
488 | #define r0 0 | ||
489 | #define r1 1 | ||
490 | #define r2 2 | ||
491 | #define r3 3 | ||
492 | #define r4 4 | ||
493 | #define r5 5 | ||
494 | #define r6 6 | ||
495 | #define r7 7 | ||
496 | #define r8 8 | ||
497 | #define r9 9 | ||
498 | #define r10 10 | ||
499 | #define r11 11 | ||
500 | #define r12 12 | ||
501 | #define r13 13 | ||
502 | #define r14 14 | ||
503 | #define r15 15 | ||
504 | #define r16 16 | ||
505 | #define r17 17 | ||
506 | #define r18 18 | ||
507 | #define r19 19 | ||
508 | #define r20 20 | ||
509 | #define r21 21 | ||
510 | #define r22 22 | ||
511 | #define r23 23 | ||
512 | #define r24 24 | ||
513 | #define r25 25 | ||
514 | #define r26 26 | ||
515 | #define r27 27 | ||
516 | #define r28 28 | ||
517 | #define r29 29 | ||
518 | #define r30 30 | ||
519 | #define r31 31 | ||
520 | |||
521 | #define cr0 0 | ||
522 | #define cr1 1 | ||
523 | #define cr2 2 | ||
524 | #define cr3 3 | ||
525 | #define cr4 4 | ||
526 | #define cr5 5 | ||
527 | #define cr6 6 | ||
528 | #define cr7 7 | ||
529 | |||
530 | #define function_prolog(func_name) .text; \ | ||
531 | .align 2; \ | ||
532 | .globl func_name; \ | ||
533 | func_name: | ||
534 | #define function_epilog(func_name) .type func_name,@function; \ | ||
535 | .size func_name,.-func_name | ||
536 | |||
537 | #define function_call(func_name) bl func_name | ||
538 | |||
539 | #define stack_frame_min 8 | ||
540 | #define stack_frame_bc 0 | ||
541 | #define stack_frame_lr 4 | ||
542 | #define stack_neg_off 0 | ||
543 | |||
544 | #endif | ||
545 | |||
546 | /*----------------------------------------------------------------------------+ | ||
547 | | Function prolog definition and other DIAB (Elf) defines. | ||
548 | +----------------------------------------------------------------------------*/ | ||
549 | #ifdef ELF_DIAB | ||
550 | |||
551 | fprolog: macro f_name | ||
552 | .text | ||
553 | .align 2 | ||
554 | .globl f_name | ||
555 | f_name: | ||
556 | endm | ||
557 | |||
558 | fepilog: macro f_name | ||
559 | .type f_name,@function | ||
560 | .size f_name,.-f_name | ||
561 | endm | ||
562 | |||
563 | #define function_prolog(func_name) fprolog func_name | ||
564 | #define function_epilog(func_name) fepilog func_name | ||
565 | #define function_call(func_name) bl func_name | ||
566 | |||
567 | #define stack_frame_min 8 | ||
568 | #define stack_frame_bc 0 | ||
569 | #define stack_frame_lr 4 | ||
570 | #define stack_neg_off 0 | ||
571 | |||
572 | #endif | ||
573 | |||
574 | /*----------------------------------------------------------------------------+ | ||
575 | | Function prolog definition and other Xlc (XCOFF) defines. | ||
576 | +----------------------------------------------------------------------------*/ | ||
577 | #ifdef XCOFF | ||
578 | |||
579 | .machine "403ga" | ||
580 | |||
581 | #define r0 0 | ||
582 | #define r1 1 | ||
583 | #define r2 2 | ||
584 | #define r3 3 | ||
585 | #define r4 4 | ||
586 | #define r5 5 | ||
587 | #define r6 6 | ||
588 | #define r7 7 | ||
589 | #define r8 8 | ||
590 | #define r9 9 | ||
591 | #define r10 10 | ||
592 | #define r11 11 | ||
593 | #define r12 12 | ||
594 | #define r13 13 | ||
595 | #define r14 14 | ||
596 | #define r15 15 | ||
597 | #define r16 16 | ||
598 | #define r17 17 | ||
599 | #define r18 18 | ||
600 | #define r19 19 | ||
601 | #define r20 20 | ||
602 | #define r21 21 | ||
603 | #define r22 22 | ||
604 | #define r23 23 | ||
605 | #define r24 24 | ||
606 | #define r25 25 | ||
607 | #define r26 26 | ||
608 | #define r27 27 | ||
609 | #define r28 28 | ||
610 | #define r29 29 | ||
611 | #define r30 30 | ||
612 | #define r31 31 | ||
613 | |||
614 | #define cr0 0 | ||
615 | #define cr1 1 | ||
616 | #define cr2 2 | ||
617 | #define cr3 3 | ||
618 | #define cr4 4 | ||
619 | #define cr5 5 | ||
620 | #define cr6 6 | ||
621 | #define cr7 7 | ||
622 | |||
623 | #define function_prolog(func_name) .csect .func_name[PR]; \ | ||
624 | .globl .func_name[PR]; \ | ||
625 | func_name: | ||
626 | |||
627 | #define function_epilog(func_name) .toc; \ | ||
628 | .csect func_name[DS]; \ | ||
629 | .globl func_name[DS]; \ | ||
630 | .long .func_name[PR]; \ | ||
631 | .long TOC[tc0] | ||
632 | |||
633 | #define function_call(func_name) .extern .func_name[PR]; \ | ||
634 | stw r2,stack_frame_toc(r1); \ | ||
635 | mfspr r2,sprg0; \ | ||
636 | bl .func_name[PR]; \ | ||
637 | lwz r2,stack_frame_toc(r1) | ||
638 | |||
639 | #define stack_frame_min 56 | ||
640 | #define stack_frame_bc 0 | ||
641 | #define stack_frame_lr 8 | ||
642 | #define stack_frame_toc 20 | ||
643 | #define stack_neg_off 276 | ||
644 | |||
645 | #endif | ||
646 | #define function_prolog(func_name) .text; \ | ||
647 | .align 2; \ | ||
648 | .globl func_name; \ | ||
649 | func_name: | ||
650 | #define function_epilog(func_name) .type func_name,@function; \ | ||
651 | .size func_name,.-func_name | ||
652 | |||
653 | #define function_call(func_name) bl func_name | ||
654 | |||
655 | /*----------------------------------------------------------------------------+ | ||
656 | | Function prolog definition for GNU | ||
657 | +----------------------------------------------------------------------------*/ | ||
658 | #ifdef _GNU_TOOL | ||
659 | |||
660 | #define function_prolog(func_name) .globl func_name; \ | ||
661 | func_name: | ||
662 | #define function_epilog(func_name) | ||
663 | |||
664 | #endif | ||
diff --git a/arch/ppc/boot/simple/rw4/rw4_init.S b/arch/ppc/boot/simple/rw4/rw4_init.S new file mode 100644 index 000000000000..b1061962e46b --- /dev/null +++ b/arch/ppc/boot/simple/rw4/rw4_init.S | |||
@@ -0,0 +1,78 @@ | |||
1 | #define VESTA | ||
2 | #include "ppc_40x.h" | ||
3 | # | ||
4 | .align 2 | ||
5 | .text | ||
6 | # | ||
7 | # added by linguohui | ||
8 | .extern initb_ebiu0, initb_config, hdw_init_finish | ||
9 | .extern initb_hsmc0, initb_hsmc1, initb_cache | ||
10 | # end added | ||
11 | .globl HdwInit | ||
12 | # | ||
13 | HdwInit: | ||
14 | # | ||
15 | #-----------------------------------------------------------------------* | ||
16 | # If we are not executing from the FLASH get out * | ||
17 | #-----------------------------------------------------------------------* | ||
18 | # SAW keep this or comment out a la Hawthorne? | ||
19 | # r3 contains NIP when used with Linux | ||
20 | # rlwinm r28, r3, 8, 24, 31 # if MSB == 0xFF -> FLASH address | ||
21 | # cmpwi r28, 0xff | ||
22 | # bne locn01 | ||
23 | # | ||
24 | # | ||
25 | #------------------------------------------------------------------------ | ||
26 | # Init_cpu. Bank registers are setup for the IBM STB. | ||
27 | #------------------------------------------------------------------------ | ||
28 | # | ||
29 | # Setup processor core clock to be driven off chip. This is GPI4 bit | ||
30 | # twenty. Setup Open Drain, Output Select, Three-State Control, and | ||
31 | # Three-State Select registers. | ||
32 | # | ||
33 | |||
34 | |||
35 | pb0pesr = 0x054 | ||
36 | pb0pear = 0x056 | ||
37 | |||
38 | mflr r30 | ||
39 | |||
40 | #----------------------------------------------------------------------------- | ||
41 | # Vectors will be at 0x1F000000 | ||
42 | # Dummy Machine check handler just does RFI before true handler gets installed | ||
43 | #----------------------------------------------------------------------------- | ||
44 | #if 1 /* xuwentao added*/ | ||
45 | #ifdef SDRAM16MB | ||
46 | lis r10,0x0000 | ||
47 | addi r10,r10,0x0000 | ||
48 | #else | ||
49 | lis r10,0x1F00 | ||
50 | addi r10,r10,0x0000 | ||
51 | #endif | ||
52 | |||
53 | mtspr evpr,r10 #EVPR: 0x0 or 0x1f000000 depending | ||
54 | isync # on SDRAM memory model used. | ||
55 | |||
56 | lis r10,0xFFFF # clear PB0_PESR because some | ||
57 | ori r10,r10,0xFFFF # transitions from flash,changed by linguohui | ||
58 | mtdcr pb0pesr,r10 # to load RAM image via RiscWatch | ||
59 | lis r10,0x0000 # cause PB0_PESR machine checks | ||
60 | mtdcr pb0pear,r10 | ||
61 | addis r10,r10,0x0000 # clear the | ||
62 | mtxer r10 # XER just in case... | ||
63 | #endif /* xuwentao*/ | ||
64 | |||
65 | bl initb_ebiu0 # init EBIU | ||
66 | |||
67 | bl initb_config # config PPC and board | ||
68 | |||
69 | |||
70 | |||
71 | |||
72 | #------------------------------------------------------------------------ | ||
73 | # EVPR setup moved to top of this function. | ||
74 | #------------------------------------------------------------------------ | ||
75 | # | ||
76 | mtlr r30 | ||
77 | blr | ||
78 | .end | ||
diff --git a/arch/ppc/boot/simple/rw4/rw4_init_brd.S b/arch/ppc/boot/simple/rw4/rw4_init_brd.S new file mode 100644 index 000000000000..386afdaad6c7 --- /dev/null +++ b/arch/ppc/boot/simple/rw4/rw4_init_brd.S | |||
@@ -0,0 +1,1125 @@ | |||
1 | /*----------------------------------------------------------------------------+ | ||
2 | | This source code has been made available to you by IBM on an AS-IS | ||
3 | | basis. Anyone receiving this source is licensed under IBM | ||
4 | | copyrights to use it in any way he or she deems fit, including | ||
5 | | copying it, modifying it, compiling it, and redistributing it either | ||
6 | | with or without modifications. No license under IBM patents or | ||
7 | | patent applications is to be implied by the copyright license. | ||
8 | | | ||
9 | | Any user of this software should understand that IBM cannot provide | ||
10 | | technical support for this software and will not be responsible for | ||
11 | | any consequences resulting from the use of this software. | ||
12 | | | ||
13 | | Any person who transfers this source code or any derivative work | ||
14 | | must include the IBM copyright notice, this paragraph, and the | ||
15 | | preceding two paragraphs in the transferred software. | ||
16 | | | ||
17 | | COPYRIGHT I B M CORPORATION 1997 | ||
18 | | LICENSED MATERIAL - PROGRAM PROPERTY OF I B M | ||
19 | +----------------------------------------------------------------------------*/ | ||
20 | /*----------------------------------------------------------------------------+ | ||
21 | | Author: Tony J. Cerreto | ||
22 | | Component: BSPS | ||
23 | | File: init_brd.s | ||
24 | | Purpose: Vesta Evaluation Board initialization subroutines. The following | ||
25 | | routines are available: | ||
26 | | 1. INITB_EBIU0: Initialize EBIU0. | ||
27 | | 2. INITB_CONFIG: Configure board. | ||
28 | | 3. INITB_HSMC0: Initialize HSMC0 (SDRAM). | ||
29 | | 4. INITB_HSMC1: Initialize HSMC1 (SDRAM). | ||
30 | | 5. INITB_CACHE: Initialize Data and Instruction Cache. | ||
31 | | 6. INITB_DCACHE: Initialize Data Cache. | ||
32 | | 7. INITB_ICACHE: Initialize Instruction Cache. | ||
33 | | 8. INITB_GET_CSPD: Get CPU Speed (Bus Speed and Processor Speed) | ||
34 | | | ||
35 | | Changes: | ||
36 | | Date: Author Comment: | ||
37 | | --------- ------ -------- | ||
38 | | 01-Mar-00 tjc Created | ||
39 | | 04-Mar-00 jfh Modified CIC_SEL3_VAL to support 1284 (Mux3 & GPIO 21-28) | ||
40 | | 04-Mar-00 jfh Modified XILINIX Reg 0 to support 1284 (Mux3 & GPIO 21-28) | ||
41 | | 04-Mar-00 jfh Modified XILINIX Reg 1 to support 1284 (Mux3 & GPIO 21-28) | ||
42 | | 04-Mar-00 jfh Modified XILINIX Reg 4 to support 1284 (Mux3 & GPIO 21-28) | ||
43 | | 19-May-00 rlb Relcoated HSMC0 to 0x1F000000 to support 32MB of contiguous | ||
44 | | SDRAM space. Changed cache ctl regs to reflect this. | ||
45 | | 22-May-00 tjc Changed initb_get_cspd interface and eliminated | ||
46 | | initb_get_bspd routines. | ||
47 | | 26-May-00 tjc Added two nop instructions after all mtxxx/mfxxx | ||
48 | | instructions due to PPC405 bug. | ||
49 | +----------------------------------------------------------------------------*/ | ||
50 | #define VESTA | ||
51 | #include "ppc_40x.h" | ||
52 | #include "stb.h" | ||
53 | |||
54 | /*----------------------------------------------------------------------------+ | ||
55 | | BOARD CONFIGURATION DEFINES | ||
56 | +----------------------------------------------------------------------------*/ | ||
57 | #define CBS0_CR_VAL 0x00000002 /* CBS control reg value */ | ||
58 | #define CIC0_CR_VAL 0xD0800448 /* CIC control reg value */ | ||
59 | #define CIC0_SEL3_VAL 0x11500000 /* CIC select 3 reg value */ | ||
60 | #define CIC0_VCR_VAL 0x00631700 /* CIC video cntl reg value */ | ||
61 | |||
62 | /*----------------------------------------------------------------------------+ | ||
63 | | EBIU0 BANK REGISTERS DEFINES | ||
64 | +----------------------------------------------------------------------------*/ | ||
65 | #define EBIU0_BRCRH0_VAL 0x00000000 /* BR High 0 (Extension Reg)*/ | ||
66 | #define EBIU0_BRCRH1_VAL 0x00000000 /* BR High 1 (Extension Reg)*/ | ||
67 | #define EBIU0_BRCRH2_VAL 0x40000000 /* BR High 2 (Extension Reg)*/ | ||
68 | #define EBIU0_BRCRH3_VAL 0x40000000 /* BR High 3 (Extension Reg)*/ | ||
69 | #define EBIU0_BRCRH4_VAL 0x00000000 /* BR High 4 (Extension Reg)*/ | ||
70 | #define EBIU0_BRCRH5_VAL 0x00000000 /* BR High 5 (Extension Reg)*/ | ||
71 | #define EBIU0_BRCRH6_VAL 0x00000000 /* BR High 6 (Extension Reg)*/ | ||
72 | #define EBIU0_BRCRH7_VAL 0x40000000 /* BR High 7 (Extension Reg)*/ | ||
73 | |||
74 | #define EBIU0_BRCR0_VAL 0xFC58BFFE /* BR 0: 16 bit Flash 4 MB */ | ||
75 | #define EBIU0_BRCR1_VAL 0xFF00BFFE /* BR 1: Ext Connector 1 MB */ | ||
76 | #if 1 | ||
77 | #define EBIU0_BRCR2_VAL 0x207CFFBE /* BR 2: Xilinx 8 MB */ | ||
78 | /* twt == 0x3f */ | ||
79 | #else | ||
80 | #define EBIU0_BRCR2_VAL 0x207CCFBE /* BR 2: Xilinx 8 MB */ | ||
81 | /* twt == 0x0f */ | ||
82 | #endif | ||
83 | #define EBIU0_BRCR3_VAL 0x407CBFBE /* BR 3: IDE Drive 8 MB */ | ||
84 | #define EBIU0_BRCR4_VAL 0xFF00BFFF /* BR 4: Disabled. 0 MB */ | ||
85 | #define EBIU0_BRCR5_VAL 0xFF00BFFF /* BR 5: Disabled. 0 MB */ | ||
86 | #define EBIU0_BRCR6_VAL 0xFF00BFFF /* BR 6: Disabled. 0 MB */ | ||
87 | #define EBIU0_BRCR7_VAL 0xCE3F0003 /* BR 7: Line Mode DMA 2 MB */ | ||
88 | |||
89 | /*----------------------------------------------------------------------------+ | ||
90 | | GPIO DEFINES | ||
91 | +----------------------------------------------------------------------------*/ | ||
92 | #define STB_GPIO0_OUTPUT (STB_GPIO0_BASE_ADDRESS+ 0x00) | ||
93 | #define STB_GPIO0_TC (STB_GPIO0_BASE_ADDRESS+ 0x04) | ||
94 | #define STB_GPIO0_OS_0_31 (STB_GPIO0_BASE_ADDRESS+ 0x08) | ||
95 | #define STB_GPIO0_OS_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x0C) | ||
96 | #define STB_GPIO0_TS_0_31 (STB_GPIO0_BASE_ADDRESS+ 0x10) | ||
97 | #define STB_GPIO0_TS_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x14) | ||
98 | #define STB_GPIO0_OD (STB_GPIO0_BASE_ADDRESS+ 0x18) | ||
99 | #define STB_GPIO0_INPUT (STB_GPIO0_BASE_ADDRESS+ 0x1C) | ||
100 | #define STB_GPIO0_R1 (STB_GPIO0_BASE_ADDRESS+ 0x20) | ||
101 | #define STB_GPIO0_R2 (STB_GPIO0_BASE_ADDRESS+ 0x24) | ||
102 | #define STB_GPIO0_R3 (STB_GPIO0_BASE_ADDRESS+ 0x28) | ||
103 | #define STB_GPIO0_IS_1_0_31 (STB_GPIO0_BASE_ADDRESS+ 0x30) | ||
104 | #define STB_GPIO0_IS_1_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x34) | ||
105 | #define STB_GPIO0_IS_2_0_31 (STB_GPIO0_BASE_ADDRESS+ 0x38) | ||
106 | #define STB_GPIO0_IS_2_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x3C) | ||
107 | #define STB_GPIO0_IS_3_0_31 (STB_GPIO0_BASE_ADDRESS+ 0x40) | ||
108 | #define STB_GPIO0_IS_3_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x44) | ||
109 | #define STB_GPIO0_SS_1 (STB_GPIO0_BASE_ADDRESS+ 0x50) | ||
110 | #define STB_GPIO0_SS_2 (STB_GPIO0_BASE_ADDRESS+ 0x54) | ||
111 | #define STB_GPIO0_SS_3 (STB_GPIO0_BASE_ADDRESS+ 0x58) | ||
112 | |||
113 | #define GPIO0_TC_VAL 0x0C020004 /* three-state control val */ | ||
114 | #define GPIO0_OS_0_31_VAL 0x51A00004 /* output select 0-31 val */ | ||
115 | #define GPIO0_OS_32_63_VAL 0x0000002F /* output select 32-63 val */ | ||
116 | #define GPIO0_TS_0_31_VAL 0x51A00000 /* three-state sel 0-31 val*/ | ||
117 | #define GPIO0_TS_32_63_VAL 0x0000000F /* three-state sel 32-63 val*/ | ||
118 | #define GPIO0_OD_VAL 0xC0000004 /* open drain val */ | ||
119 | #define GPIO0_IS_1_0_31_VAL 0x50000151 /* input select 1 0-31 val */ | ||
120 | #define GPIO0_IS_1_32_63_VAL 0x00000000 /* input select 1 32-63 val */ | ||
121 | #define GPIO0_IS_2_0_31_VAL 0x00000000 /* input select 2 0-31 val */ | ||
122 | #define GPIO0_IS_2_32_63_VAL 0x00000000 /* input select 2 32-63 val */ | ||
123 | #define GPIO0_IS_3_0_31_VAL 0x00000440 /* input select 3 0-31 val */ | ||
124 | #define GPIO0_IS_3_32_63_VAL 0x00000000 /* input select 3 32-63 val */ | ||
125 | #define GPIO0_SS_1_VAL 0x00000000 /* sync select 1 val */ | ||
126 | #define GPIO0_SS_2_VAL 0x00000000 /* sync select 2 val */ | ||
127 | #define GPIO0_SS_3_VAL 0x00000000 /* sync select 3 val */ | ||
128 | |||
129 | /*----------------------------------------------------------------------------+ | ||
130 | | XILINX DEFINES | ||
131 | +----------------------------------------------------------------------------*/ | ||
132 | #define STB_XILINX_LED (STB_FPGA_BASE_ADDRESS+ 0x0100) | ||
133 | #define STB_XILINX1_REG0 (STB_FPGA_BASE_ADDRESS+ 0x40000) | ||
134 | #define STB_XILINX1_REG1 (STB_FPGA_BASE_ADDRESS+ 0x40002) | ||
135 | #define STB_XILINX1_REG2 (STB_FPGA_BASE_ADDRESS+ 0x40004) | ||
136 | #define STB_XILINX1_REG3 (STB_FPGA_BASE_ADDRESS+ 0x40006) | ||
137 | #define STB_XILINX1_REG4 (STB_FPGA_BASE_ADDRESS+ 0x40008) | ||
138 | #define STB_XILINX1_REG5 (STB_FPGA_BASE_ADDRESS+ 0x4000A) | ||
139 | #define STB_XILINX1_REG6 (STB_FPGA_BASE_ADDRESS+ 0x4000C) | ||
140 | #define STB_XILINX1_ID (STB_FPGA_BASE_ADDRESS+ 0x4000E) | ||
141 | #define STB_XILINX1_FLUSH (STB_FPGA_BASE_ADDRESS+ 0x4000E) | ||
142 | #define STB_XILINX2_REG0 (STB_FPGA_BASE_ADDRESS+ 0x80000) | ||
143 | #define STB_XILINX2_REG1 (STB_FPGA_BASE_ADDRESS+ 0x80002) | ||
144 | #define STB_XILINX2_REG2 (STB_FPGA_BASE_ADDRESS+ 0x80004) | ||
145 | |||
146 | #define XILINX1_R0_VAL 0x2440 /* Xilinx 1 Register 0 Val */ | ||
147 | #define XILINX1_R1_VAL 0x0025 /* Xilinx 1 Register 1 Val */ | ||
148 | #define XILINX1_R2_VAL 0x0441 /* Xilinx 1 Register 2 Val */ | ||
149 | #define XILINX1_R3_VAL 0x0008 /* Xilinx 1 Register 3 Val */ | ||
150 | #define XILINX1_R4_VAL 0x0100 /* Xilinx 1 Register 4 Val */ | ||
151 | #define XILINX1_R5_VAL 0x6810 /* Xilinx 1 Register 5 Val */ | ||
152 | #define XILINX1_R6_VAL 0x0000 /* Xilinx 1 Register 6 Val */ | ||
153 | #if 0 | ||
154 | #define XILINX2_R0_VAL 0x0008 /* Xilinx 2 Register 0 Val */ | ||
155 | #define XILINX2_R1_VAL 0x0000 /* Xilinx 2 Register 1 Val */ | ||
156 | #else | ||
157 | #define XILINX2_R0_VAL 0x0018 /* disable IBM IrDA RxD */ | ||
158 | #define XILINX2_R1_VAL 0x0008 /* enable SICC MAX chip */ | ||
159 | #endif | ||
160 | #define XILINX2_R2_VAL 0x0000 /* Xilinx 2 Register 2 Val */ | ||
161 | |||
162 | /*----------------------------------------------------------------------------+ | ||
163 | | HSMC BANK REGISTERS DEFINES | ||
164 | +----------------------------------------------------------------------------*/ | ||
165 | #ifdef SDRAM16MB | ||
166 | #define HSMC0_BR0_VAL 0x000D2D55 /* 0x1F000000-007FFFFF R/W */ | ||
167 | #define HSMC0_BR1_VAL 0x008D2D55 /* 0x1F800000-1FFFFFFF R/W */ | ||
168 | #else | ||
169 | #define HSMC0_BR0_VAL 0x1F0D2D55 /* 0x1F000000-007FFFFF R/W */ | ||
170 | #define HSMC0_BR1_VAL 0x1F8D2D55 /* 0x1F800000-1FFFFFFF R/W */ | ||
171 | #endif | ||
172 | #define HSMC1_BR0_VAL 0xA00D2D55 /* 0xA0000000-A07FFFFF R/W */ | ||
173 | #define HSMC1_BR1_VAL 0xA08D2D55 /* 0xA0800000-A0FFFFFF R/W */ | ||
174 | |||
175 | /*----------------------------------------------------------------------------+ | ||
176 | | CACHE DEFINES | ||
177 | +----------------------------------------------------------------------------*/ | ||
178 | #define DCACHE_NLINES 128 /* no. D-cache lines */ | ||
179 | #define DCACHE_NBYTES 32 /* no. bytes/ D-cache line */ | ||
180 | #define ICACHE_NLINES 256 /* no. I-cache lines */ | ||
181 | #define ICACHE_NBYTES 32 /* no. bytes/ I-cache line */ | ||
182 | #ifdef SDRAM16MB | ||
183 | #define DCACHE_ENABLE 0x80000000 /* D-cache regions to enable*/ | ||
184 | #define ICACHE_ENABLE 0x80000001 /* I-cache regions to enable*/ | ||
185 | #else | ||
186 | #define DCACHE_ENABLE 0x18000000 /* D-cache regions to enable*/ | ||
187 | #define ICACHE_ENABLE 0x18000001 /* I-cache regions to enable*/ | ||
188 | #endif | ||
189 | |||
190 | /*----------------------------------------------------------------------------+ | ||
191 | | CPU CORE SPEED CALCULATION DEFINES | ||
192 | +----------------------------------------------------------------------------*/ | ||
193 | #define GCS_LCNT 500000 /* CPU speed loop count */ | ||
194 | #define GCS_TROW_BYTES 8 /* no. bytes in table row */ | ||
195 | #define GCS_CTICK_TOL 100 /* allowable clock tick tol */ | ||
196 | #define GCS_NMULT 4 /* no. of core speed mults */ | ||
197 | |||
198 | /*--------------------------------------------------------------------+ | ||
199 | | No. 13.5Mhz | ||
200 | | Clock Ticks | ||
201 | | based on a | ||
202 | | loop count Bus | ||
203 | | of 100,000 Speed | ||
204 | +--------------------------------------------------------------------*/ | ||
205 | gcs_lookup_table: | ||
206 | .int 50000, 54000000 /* 54.0 Mhz */ | ||
207 | .int 66667, 40500000 /* 40.5 Mhz */ | ||
208 | .int 54545, 49500000 /* 49.5 Mhz */ | ||
209 | .int 46154, 58500000 /* 58.5 Mhz */ | ||
210 | .int 0, 0 /* end of table flag */ | ||
211 | |||
212 | |||
213 | /*****************************************************************************+ | ||
214 | | XXXXXXX XXX XXX XXXXXX XXXXXXX XXXXXX XX XX XX XXXX | ||
215 | | XX X XX XX X XX X XX X XX XX XXX XX XXXX XX | ||
216 | | XX X XXX XX XX X XX XX XXXX XX XX XX XX | ||
217 | | XXXX X XX XXXX XXXXX XX XXXX XX XX XX | ||
218 | | XX X XXX XX XX X XX XX XX XXX XXXXXX XX | ||
219 | | XX X XX XX XX XX X XX XX XX XX XX XX XX XX | ||
220 | | XXXXXXX XXX XXX XXXX XXXXXXX XXX XX XX XX XX XX XXXXXXX | ||
221 | +*****************************************************************************/ | ||
222 | /****************************************************************************** | ||
223 | | | ||
224 | | Routine: INITB_EBIU0. | ||
225 | | | ||
226 | | Purpose: Initialize all the EBIU0 Bank Registers | ||
227 | | Parameters: None. | ||
228 | | Returns: None. | ||
229 | | | ||
230 | ******************************************************************************/ | ||
231 | function_prolog(initb_ebiu0) | ||
232 | /*--------------------------------------------------------------------+ | ||
233 | | Set EBIU0 Bank 0 | ||
234 | +--------------------------------------------------------------------*/ | ||
235 | lis r10,EBIU0_BRCR0_VAL@h | ||
236 | ori r10,r10,EBIU0_BRCR0_VAL@l | ||
237 | mtdcr ebiu0_brcr0,r10 | ||
238 | lis r10,EBIU0_BRCRH0_VAL@h | ||
239 | ori r10,r10,EBIU0_BRCRH0_VAL@l | ||
240 | mtdcr ebiu0_brcrh0,r10 | ||
241 | |||
242 | /*--------------------------------------------------------------------+ | ||
243 | | Set EBIU0 Bank 1 | ||
244 | +--------------------------------------------------------------------*/ | ||
245 | lis r10,EBIU0_BRCR1_VAL@h | ||
246 | ori r10,r10,EBIU0_BRCR1_VAL@l | ||
247 | mtdcr ebiu0_brcr1,r10 | ||
248 | lis r10,EBIU0_BRCRH1_VAL@h | ||
249 | ori r10,r10,EBIU0_BRCRH1_VAL@l | ||
250 | mtdcr ebiu0_brcrh1,r10 | ||
251 | |||
252 | /*--------------------------------------------------------------------+ | ||
253 | | Set EBIU0 Bank 2 | ||
254 | +--------------------------------------------------------------------*/ | ||
255 | lis r10,EBIU0_BRCR2_VAL@h | ||
256 | ori r10,r10,EBIU0_BRCR2_VAL@l | ||
257 | mtdcr ebiu0_brcr2,r10 | ||
258 | lis r10,EBIU0_BRCRH2_VAL@h | ||
259 | ori r10,r10,EBIU0_BRCRH2_VAL@l | ||
260 | mtdcr ebiu0_brcrh2,r10 | ||
261 | |||
262 | /*--------------------------------------------------------------------+ | ||
263 | | Set EBIU0 Bank 3 | ||
264 | +--------------------------------------------------------------------*/ | ||
265 | lis r10,EBIU0_BRCR3_VAL@h | ||
266 | ori r10,r10,EBIU0_BRCR3_VAL@l | ||
267 | mtdcr ebiu0_brcr3,r10 | ||
268 | lis r10,EBIU0_BRCRH3_VAL@h | ||
269 | ori r10,r10,EBIU0_BRCRH3_VAL@l | ||
270 | mtdcr ebiu0_brcrh3,r10 | ||
271 | |||
272 | /*--------------------------------------------------------------------+ | ||
273 | | Set EBIU0 Bank 4 | ||
274 | +--------------------------------------------------------------------*/ | ||
275 | lis r10,EBIU0_BRCR4_VAL@h | ||
276 | ori r10,r10,EBIU0_BRCR4_VAL@l | ||
277 | mtdcr ebiu0_brcr4,r10 | ||
278 | lis r10,EBIU0_BRCRH4_VAL@h | ||
279 | ori r10,r10,EBIU0_BRCRH4_VAL@l | ||
280 | mtdcr ebiu0_brcrh4,r10 | ||
281 | |||
282 | /*--------------------------------------------------------------------+ | ||
283 | | Set EBIU0 Bank 5 | ||
284 | +--------------------------------------------------------------------*/ | ||
285 | lis r10,EBIU0_BRCR5_VAL@h | ||
286 | ori r10,r10,EBIU0_BRCR5_VAL@l | ||
287 | mtdcr ebiu0_brcr5,r10 | ||
288 | lis r10,EBIU0_BRCRH5_VAL@h | ||
289 | ori r10,r10,EBIU0_BRCRH5_VAL@l | ||
290 | mtdcr ebiu0_brcrh5,r10 | ||
291 | |||
292 | /*--------------------------------------------------------------------+ | ||
293 | | Set EBIU0 Bank 6 | ||
294 | +--------------------------------------------------------------------*/ | ||
295 | lis r10,EBIU0_BRCR6_VAL@h | ||
296 | ori r10,r10,EBIU0_BRCR6_VAL@l | ||
297 | mtdcr ebiu0_brcr6,r10 | ||
298 | lis r10,EBIU0_BRCRH6_VAL@h | ||
299 | ori r10,r10,EBIU0_BRCRH6_VAL@l | ||
300 | mtdcr ebiu0_brcrh6,r10 | ||
301 | |||
302 | /*--------------------------------------------------------------------+ | ||
303 | | Set EBIU0 Bank 7 | ||
304 | +--------------------------------------------------------------------*/ | ||
305 | lis r10,EBIU0_BRCR7_VAL@h | ||
306 | ori r10,r10,EBIU0_BRCR7_VAL@l | ||
307 | mtdcr ebiu0_brcr7,r10 | ||
308 | lis r10,EBIU0_BRCRH7_VAL@h | ||
309 | ori r10,r10,EBIU0_BRCRH7_VAL@l | ||
310 | mtdcr ebiu0_brcrh7,r10 | ||
311 | |||
312 | blr | ||
313 | function_epilog(initb_ebiu0) | ||
314 | |||
315 | |||
316 | /****************************************************************************** | ||
317 | | | ||
318 | | Routine: INITB_CONFIG | ||
319 | | | ||
320 | | Purpose: Configure the Vesta Evaluation Board. The following items | ||
321 | | will be configured: | ||
322 | | 1. Cross-Bar Switch. | ||
323 | | 2. Chip Interconnect. | ||
324 | | 3. Clear/reset key PPC registers. | ||
325 | | 4. Xilinx and GPIO Registers. | ||
326 | | | ||
327 | | Returns: None. | ||
328 | | | ||
329 | ******************************************************************************/ | ||
330 | function_prolog(initb_config) | ||
331 | /*--------------------------------------------------------------------+ | ||
332 | | Init CROSS-BAR SWITCH | ||
333 | +--------------------------------------------------------------------*/ | ||
334 | lis r10,CBS0_CR_VAL@h /* r10 <- CBS Cntl Reg val */ | ||
335 | ori r10,r10,CBS0_CR_VAL@l | ||
336 | mtdcr cbs0_cr,r10 | ||
337 | |||
338 | /*--------------------------------------------------------------------+ | ||
339 | | Init Chip-Interconnect (CIC) Registers | ||
340 | +--------------------------------------------------------------------*/ | ||
341 | lis r10,CIC0_CR_VAL@h /* r10 <- CIC Cntl Reg val */ | ||
342 | ori r10,r10,CIC0_CR_VAL@l | ||
343 | mtdcr cic0_cr,r10 | ||
344 | |||
345 | lis r10,CIC0_SEL3_VAL@h /* r10 <- CIC SEL3 Reg val */ | ||
346 | ori r10,r10,CIC0_SEL3_VAL@l | ||
347 | mtdcr cic0_sel3,r10 | ||
348 | |||
349 | lis r10,CIC0_VCR_VAL@h /* r10 <- CIC Vid C-Reg val */ | ||
350 | ori r10,r10,CIC0_VCR_VAL@l | ||
351 | mtdcr cic0_vcr,r10 | ||
352 | |||
353 | /*--------------------------------------------------------------------+ | ||
354 | | Clear SGR and DCWR | ||
355 | +--------------------------------------------------------------------*/ | ||
356 | li r10,0x0000 | ||
357 | mtspr sgr,r10 | ||
358 | mtspr dcwr,r10 | ||
359 | |||
360 | /*--------------------------------------------------------------------+ | ||
361 | | Clear/set up some machine state registers. | ||
362 | +--------------------------------------------------------------------*/ | ||
363 | li r10,0x0000 /* r10 <- 0 */ | ||
364 | mtdcr ebiu0_besr,r10 /* clr Bus Err Syndrome Reg */ | ||
365 | mtspr esr,r10 /* clr Exceptn Syndrome Reg */ | ||
366 | mttcr r10 /* timer control register */ | ||
367 | |||
368 | mtdcr uic0_er,r10 /* disable all interrupts */ | ||
369 | |||
370 | /* UIC_IIC0 | UIC_IIC1 | UIC_U0 | UIC_IR_RCV | UIC_IR_XMIT */ | ||
371 | lis r10, 0x00600e00@h | ||
372 | ori r10,r10,0x00600e00@l | ||
373 | mtdcr uic0_pr,r10 | ||
374 | |||
375 | li r10,0x00000020 /* UIC_EIR1 */ | ||
376 | mtdcr uic0_tr,r10 | ||
377 | |||
378 | lis r10,0xFFFF /* r10 <- 0xFFFFFFFF */ | ||
379 | ori r10,r10,0xFFFF /* */ | ||
380 | mtdbsr r10 /* clear/reset the dbsr */ | ||
381 | mtdcr uic0_sr,r10 /* clear pending interrupts */ | ||
382 | |||
383 | li r10,0x1000 /* set Machine Exception bit*/ | ||
384 | oris r10,r10,0x2 /* set Criticl Exception bit*/ | ||
385 | mtmsr r10 /* change MSR */ | ||
386 | |||
387 | /*--------------------------------------------------------------------+ | ||
388 | | Clear XER. | ||
389 | +--------------------------------------------------------------------*/ | ||
390 | li r10,0x0000 | ||
391 | mtxer r10 | ||
392 | |||
393 | /*--------------------------------------------------------------------+ | ||
394 | | Init GPIO0 Registers | ||
395 | +--------------------------------------------------------------------*/ | ||
396 | lis r10, STB_GPIO0_TC@h /* Three-state control */ | ||
397 | ori r10,r10,STB_GPIO0_TC@l | ||
398 | lis r11, GPIO0_TC_VAL@h | ||
399 | ori r11,r11,GPIO0_TC_VAL@l | ||
400 | stw r11,0(r10) | ||
401 | |||
402 | lis r10, STB_GPIO0_OS_0_31@h /* output select 0-31 */ | ||
403 | ori r10,r10,STB_GPIO0_OS_0_31@l | ||
404 | lis r11, GPIO0_OS_0_31_VAL@h | ||
405 | ori r11,r11,GPIO0_OS_0_31_VAL@l | ||
406 | stw r11,0(r10) | ||
407 | |||
408 | lis r10, STB_GPIO0_OS_32_63@h /* output select 32-63 */ | ||
409 | ori r10,r10,STB_GPIO0_OS_32_63@l | ||
410 | lis r11, GPIO0_OS_32_63_VAL@h | ||
411 | ori r11,r11,GPIO0_OS_32_63_VAL@l | ||
412 | stw r11,0(r10) | ||
413 | |||
414 | lis r10, STB_GPIO0_TS_0_31@h /* three-state select 0-31 */ | ||
415 | ori r10,r10,STB_GPIO0_TS_0_31@l | ||
416 | lis r11, GPIO0_TS_0_31_VAL@h | ||
417 | ori r11,r11,GPIO0_TS_0_31_VAL@l | ||
418 | stw r11,0(r10) | ||
419 | |||
420 | lis r10, STB_GPIO0_TS_32_63@h /* three-state select 32-63 */ | ||
421 | ori r10,r10,STB_GPIO0_TS_32_63@l | ||
422 | lis r11, GPIO0_TS_32_63_VAL@h | ||
423 | ori r11,r11,GPIO0_TS_32_63_VAL@l | ||
424 | stw r11,0(r10) | ||
425 | |||
426 | lis r10, STB_GPIO0_OD@h /* open drain */ | ||
427 | ori r10,r10,STB_GPIO0_OD@l | ||
428 | lis r11, GPIO0_OD_VAL@h | ||
429 | ori r11,r11,GPIO0_OD_VAL@l | ||
430 | stw r11,0(r10) | ||
431 | |||
432 | lis r10, STB_GPIO0_IS_1_0_31@h /* input select 1, 0-31 */ | ||
433 | ori r10,r10,STB_GPIO0_IS_1_0_31@l | ||
434 | lis r11, GPIO0_IS_1_0_31_VAL@h | ||
435 | ori r11,r11,GPIO0_IS_1_0_31_VAL@l | ||
436 | stw r11,0(r10) | ||
437 | |||
438 | lis r10, STB_GPIO0_IS_1_32_63@h /* input select 1, 32-63 */ | ||
439 | ori r10,r10,STB_GPIO0_IS_1_32_63@l | ||
440 | lis r11, GPIO0_IS_1_32_63_VAL@h | ||
441 | ori r11,r11,GPIO0_IS_1_32_63_VAL@l | ||
442 | stw r11,0(r10) | ||
443 | |||
444 | lis r10, STB_GPIO0_IS_2_0_31@h /* input select 2, 0-31 */ | ||
445 | ori r10,r10,STB_GPIO0_IS_2_0_31@l | ||
446 | lis r11, GPIO0_IS_2_0_31_VAL@h | ||
447 | ori r11,r11,GPIO0_IS_2_0_31_VAL@l | ||
448 | stw r11,0(r10) | ||
449 | |||
450 | lis r10, STB_GPIO0_IS_2_32_63@h /* input select 2, 32-63 */ | ||
451 | ori r10,r10,STB_GPIO0_IS_2_32_63@l | ||
452 | lis r11, GPIO0_IS_2_32_63_VAL@h | ||
453 | ori r11,r11,GPIO0_IS_2_32_63_VAL@l | ||
454 | stw r11,0(r10) | ||
455 | |||
456 | lis r10, STB_GPIO0_IS_3_0_31@h /* input select 3, 0-31 */ | ||
457 | ori r10,r10,STB_GPIO0_IS_3_0_31@l | ||
458 | lis r11, GPIO0_IS_3_0_31_VAL@h | ||
459 | ori r11,r11,GPIO0_IS_3_0_31_VAL@l | ||
460 | stw r11,0(r10) | ||
461 | |||
462 | lis r10, STB_GPIO0_IS_3_32_63@h /* input select 3, 32-63 */ | ||
463 | ori r10,r10,STB_GPIO0_IS_3_32_63@l | ||
464 | lis r11, GPIO0_IS_3_32_63_VAL@h | ||
465 | ori r11,r11,GPIO0_IS_3_32_63_VAL@l | ||
466 | stw r11,0(r10) | ||
467 | |||
468 | lis r10, STB_GPIO0_SS_1@h /* sync select 1 */ | ||
469 | ori r10,r10,STB_GPIO0_SS_1@l | ||
470 | lis r11, GPIO0_SS_1_VAL@h | ||
471 | ori r11,r11,GPIO0_SS_1_VAL@l | ||
472 | stw r11,0(r10) | ||
473 | |||
474 | lis r10, STB_GPIO0_SS_2@h /* sync select 2 */ | ||
475 | ori r10,r10,STB_GPIO0_SS_2@l | ||
476 | lis r11, GPIO0_SS_2_VAL@h | ||
477 | ori r11,r11,GPIO0_SS_2_VAL@l | ||
478 | stw r11,0(r10) | ||
479 | |||
480 | lis r10, STB_GPIO0_SS_3@h /* sync select 3 */ | ||
481 | ori r10,r10,STB_GPIO0_SS_3@l | ||
482 | lis r11, GPIO0_SS_3_VAL@h | ||
483 | ori r11,r11,GPIO0_SS_3_VAL@l | ||
484 | stw r11,0(r10) | ||
485 | |||
486 | /*--------------------------------------------------------------------+ | ||
487 | | Init Xilinx #1 Registers | ||
488 | +--------------------------------------------------------------------*/ | ||
489 | lis r10, STB_XILINX1_REG0@h /* init Xilinx1 Reg 0 */ | ||
490 | ori r10,r10,STB_XILINX1_REG0@l | ||
491 | li r11,XILINX1_R0_VAL | ||
492 | sth r11,0(r10) | ||
493 | |||
494 | lis r10, STB_XILINX1_REG1@h /* init Xilinx1 Reg 1 */ | ||
495 | ori r10,r10,STB_XILINX1_REG1@l | ||
496 | li r11,XILINX1_R1_VAL | ||
497 | sth r11,0(r10) | ||
498 | |||
499 | lis r10, STB_XILINX1_REG2@h /* init Xilinx1 Reg 2 */ | ||
500 | ori r10,r10,STB_XILINX1_REG2@l | ||
501 | li r11,XILINX1_R2_VAL | ||
502 | sth r11,0(r10) | ||
503 | |||
504 | lis r10, STB_XILINX1_REG3@h /* init Xilinx1 Reg 3 */ | ||
505 | ori r10,r10,STB_XILINX1_REG3@l | ||
506 | li r11,XILINX1_R3_VAL | ||
507 | sth r11,0(r10) | ||
508 | |||
509 | lis r10, STB_XILINX1_REG4@h /* init Xilinx1 Reg 4 */ | ||
510 | ori r10,r10,STB_XILINX1_REG4@l | ||
511 | li r11,XILINX1_R4_VAL | ||
512 | sth r11,0(r10) | ||
513 | |||
514 | lis r10, STB_XILINX1_REG5@h /* init Xilinx1 Reg 5 */ | ||
515 | ori r10,r10,STB_XILINX1_REG5@l | ||
516 | li r11,XILINX1_R5_VAL | ||
517 | sth r11,0(r10) | ||
518 | |||
519 | lis r10, STB_XILINX1_REG6@h /* init Xilinx1 Reg 6 */ | ||
520 | ori r10,r10,STB_XILINX1_REG6@l | ||
521 | li r11,XILINX1_R6_VAL | ||
522 | sth r11,0(r10) | ||
523 | |||
524 | lis r10, STB_XILINX1_FLUSH@h /* latch registers in Xilinx*/ | ||
525 | ori r10,r10,STB_XILINX1_FLUSH@l | ||
526 | li r11,0x0000 | ||
527 | sth r11,0(r10) | ||
528 | |||
529 | /*--------------------------------------------------------------------+ | ||
530 | | Init Xilinx #2 Registers | ||
531 | +--------------------------------------------------------------------*/ | ||
532 | lis r10, STB_XILINX2_REG0@h /* init Xilinx2 Reg 0 */ | ||
533 | ori r10,r10,STB_XILINX2_REG0@l | ||
534 | li r11,XILINX2_R0_VAL | ||
535 | sth r11,0(r10) | ||
536 | |||
537 | lis r10, STB_XILINX2_REG1@h /* init Xilinx2 Reg 1 */ | ||
538 | ori r10,r10,STB_XILINX2_REG1@l | ||
539 | li r11,XILINX2_R1_VAL | ||
540 | sth r11,0(r10) | ||
541 | |||
542 | lis r10, STB_XILINX2_REG2@h /* init Xilinx2 Reg 2 */ | ||
543 | ori r10,r10,STB_XILINX2_REG2@l | ||
544 | li r11,XILINX2_R2_VAL | ||
545 | sth r11,0(r10) | ||
546 | |||
547 | blr | ||
548 | function_epilog(initb_config) | ||
549 | |||
550 | |||
551 | /****************************************************************************** | ||
552 | | | ||
553 | | Routine: INITB_HSMC0. | ||
554 | | | ||
555 | | Purpose: Initialize the HSMC0 Registers for SDRAM | ||
556 | | Parameters: None. | ||
557 | | Returns: R3 = 0: Successful | ||
558 | | = -1: Unsuccessful, SDRAM did not reset properly. | ||
559 | | | ||
560 | ******************************************************************************/ | ||
561 | function_prolog(initb_hsmc0) | ||
562 | mflr r0 /* Save return addr */ | ||
563 | |||
564 | /*--------------------------------------------------------------------+ | ||
565 | | Set Global SDRAM Controller to recommended default | ||
566 | +--------------------------------------------------------------------*/ | ||
567 | lis r10,0x6C00 | ||
568 | ori r10,r10,0x0000 | ||
569 | mtdcr hsmc0_gr,r10 | ||
570 | |||
571 | /*--------------------------------------------------------------------+ | ||
572 | | Set HSMC0 Data Register to recommended default | ||
573 | +--------------------------------------------------------------------*/ | ||
574 | lis r10,0x0037 | ||
575 | ori r10,r10,0x0000 | ||
576 | mtdcr hsmc0_data,r10 | ||
577 | |||
578 | /*--------------------------------------------------------------------+ | ||
579 | | Init HSMC0 Bank Register 0 | ||
580 | +--------------------------------------------------------------------*/ | ||
581 | lis r10,HSMC0_BR0_VAL@h | ||
582 | ori r10,r10,HSMC0_BR0_VAL@l | ||
583 | mtdcr hsmc0_br0,r10 | ||
584 | |||
585 | /*--------------------------------------------------------------------+ | ||
586 | | Init HSMC0 Bank Register 1 | ||
587 | +--------------------------------------------------------------------*/ | ||
588 | lis r10,HSMC0_BR1_VAL@h | ||
589 | ori r10,r10,HSMC0_BR1_VAL@l | ||
590 | mtdcr hsmc0_br1,r10 | ||
591 | |||
592 | /*--------------------------------------------------------------------+ | ||
593 | | Set HSMC0 Control Reg 0 | ||
594 | +--------------------------------------------------------------------*/ | ||
595 | lis r10,0x8077 /* PRECHARGE ALL DEVICE BKS */ | ||
596 | ori r10,r10,0x0000 | ||
597 | mtdcr hsmc0_cr0,r10 | ||
598 | li r3,0x0000 | ||
599 | bl hsmc_cr_wait /* wait for op completion */ | ||
600 | cmpwi cr0,r3,0x0000 | ||
601 | bne cr0,hsmc0_err | ||
602 | |||
603 | lis r10,0x8078 /* AUTO-REFRESH */ | ||
604 | ori r10,r10,0x0000 | ||
605 | mtdcr hsmc0_cr0,r10 | ||
606 | li r3,0x0000 | ||
607 | bl hsmc_cr_wait /* wait for op completion */ | ||
608 | cmpwi cr0,r3,0x0000 | ||
609 | bne cr0,hsmc0_err | ||
610 | |||
611 | lis r10,0x8070 /* PROG MODE W/DATA REG VAL */ | ||
612 | ori r10,r10,0x8000 | ||
613 | mtdcr hsmc0_cr0,r10 | ||
614 | li r3,0x0000 | ||
615 | bl hsmc_cr_wait /* wait for op completion */ | ||
616 | cmpwi cr0,r3,0x0000 | ||
617 | bne hsmc0_err | ||
618 | |||
619 | /*--------------------------------------------------------------------+ | ||
620 | | Set HSMC0 Control Reg 1 | ||
621 | +--------------------------------------------------------------------*/ | ||
622 | lis r10,0x8077 /* PRECHARGE ALL DEVICE BKS */ | ||
623 | ori r10,r10,0x0000 | ||
624 | mtdcr hsmc0_cr1,r10 | ||
625 | li r3,0x0001 | ||
626 | bl hsmc_cr_wait /* wait for op completion */ | ||
627 | cmpwi cr0,r3,0x0000 | ||
628 | bne cr0,hsmc0_err | ||
629 | |||
630 | lis r10,0x8078 /* AUTO-REFRESH */ | ||
631 | ori r10,r10,0x0000 | ||
632 | mtdcr hsmc0_cr1,r10 | ||
633 | li r3,0x0001 | ||
634 | bl hsmc_cr_wait /* wait for op completion */ | ||
635 | cmpwi cr0,r3,0x0000 | ||
636 | bne cr0,hsmc0_err | ||
637 | |||
638 | lis r10,0x8070 /* PROG MODE W/DATA REG VAL */ | ||
639 | ori r10,r10,0x8000 | ||
640 | mtdcr hsmc0_cr1,r10 | ||
641 | li r3,0x0001 | ||
642 | bl hsmc_cr_wait /* wait for op completion */ | ||
643 | cmpwi cr0,r3,0x0000 | ||
644 | bne cr0,hsmc0_err | ||
645 | |||
646 | /*--------------------------------------------------------------------+ | ||
647 | | Set HSMC0 Refresh Register | ||
648 | +--------------------------------------------------------------------*/ | ||
649 | lis r10,0x0FE1 | ||
650 | ori r10,r10,0x0000 | ||
651 | mtdcr hsmc0_crr,r10 | ||
652 | li r3,0 | ||
653 | |||
654 | hsmc0_err: | ||
655 | mtlr r0 | ||
656 | blr | ||
657 | function_epilog(initb_hsmc0) | ||
658 | |||
659 | |||
660 | /****************************************************************************** | ||
661 | | | ||
662 | | Routine: INITB_HSMC1. | ||
663 | | | ||
664 | | Purpose: Initialize the HSMC1 Registers for SDRAM | ||
665 | | Parameters: None. | ||
666 | | Returns: R3 = 0: Successful | ||
667 | | = -1: Unsuccessful, SDRAM did not reset properly. | ||
668 | | | ||
669 | ******************************************************************************/ | ||
670 | function_prolog(initb_hsmc1) | ||
671 | mflr r0 /* Save return addr */ | ||
672 | |||
673 | /*--------------------------------------------------------------------+ | ||
674 | | Set Global SDRAM Controller to recommended default | ||
675 | +--------------------------------------------------------------------*/ | ||
676 | lis r10,0x6C00 | ||
677 | ori r10,r10,0x0000 | ||
678 | mtdcr hsmc1_gr,r10 | ||
679 | |||
680 | /*--------------------------------------------------------------------+ | ||
681 | | Set HSMC1 Data Register to recommended default | ||
682 | +--------------------------------------------------------------------*/ | ||
683 | lis r10,0x0037 | ||
684 | ori r10,r10,0x0000 | ||
685 | mtdcr hsmc1_data,r10 | ||
686 | |||
687 | /*--------------------------------------------------------------------+ | ||
688 | | Init HSMC1 Bank Register 0 | ||
689 | +--------------------------------------------------------------------*/ | ||
690 | lis r10,HSMC1_BR0_VAL@h | ||
691 | ori r10,r10,HSMC1_BR0_VAL@l | ||
692 | mtdcr hsmc1_br0,r10 | ||
693 | |||
694 | /*--------------------------------------------------------------------+ | ||
695 | | Init HSMC1 Bank Register 1 | ||
696 | +--------------------------------------------------------------------*/ | ||
697 | lis r10,HSMC1_BR1_VAL@h | ||
698 | ori r10,r10,HSMC1_BR1_VAL@l | ||
699 | mtdcr hsmc1_br1,r10 | ||
700 | |||
701 | /*--------------------------------------------------------------------+ | ||
702 | | Set HSMC1 Control Reg 0 | ||
703 | +--------------------------------------------------------------------*/ | ||
704 | lis r10,0x8077 /* PRECHARGE ALL DEVICE BANKS */ | ||
705 | ori r10,r10,0x0000 | ||
706 | mtdcr hsmc1_cr0,r10 | ||
707 | li r3,0x0002 | ||
708 | bl hsmc_cr_wait /* wait for operation completion */ | ||
709 | cmpwi cr0,r3,0x0000 | ||
710 | bne hsmc1_err | ||
711 | |||
712 | lis r10,0x8078 /* AUTO-REFRESH */ | ||
713 | ori r10,r10,0x0000 | ||
714 | mtdcr hsmc1_cr0,r10 | ||
715 | li r3,0x0002 | ||
716 | bl hsmc_cr_wait /* wait for operation completion */ | ||
717 | cmpwi cr0,r3,0x0000 | ||
718 | bne hsmc1_err | ||
719 | |||
720 | lis r10,0x8070 /* PROGRAM MODE W/DATA REG VALUE */ | ||
721 | ori r10,r10,0x8000 | ||
722 | mtdcr hsmc1_cr0,r10 | ||
723 | li r3,0x0002 | ||
724 | bl hsmc_cr_wait /* wait for operation completion */ | ||
725 | cmpwi cr0,r3,0x0000 | ||
726 | bne hsmc1_err | ||
727 | |||
728 | /*--------------------------------------------------------------------+ | ||
729 | | Set HSMC1 Control Reg 1 | ||
730 | +--------------------------------------------------------------------*/ | ||
731 | lis r10,0x8077 /* PRECHARGE ALL DEVICE BKS */ | ||
732 | ori r10,r10,0x0000 | ||
733 | mtdcr hsmc1_cr1,r10 | ||
734 | li r3,0x0003 | ||
735 | bl hsmc_cr_wait /* wait for op completion */ | ||
736 | cmpwi cr0,r3,0x0000 | ||
737 | bne hsmc1_err | ||
738 | |||
739 | lis r10,0x8078 /* AUTO-REFRESH */ | ||
740 | ori r10,r10,0x0000 | ||
741 | mtdcr hsmc1_cr1,r10 | ||
742 | li r3,0x0003 | ||
743 | bl hsmc_cr_wait /* wait for op completion */ | ||
744 | cmpwi cr0,r3,0x0000 | ||
745 | bne hsmc1_err | ||
746 | |||
747 | lis r10,0x8070 /* PROG MODE W/DATA REG VAL */ | ||
748 | ori r10,r10,0x8000 | ||
749 | mtdcr hsmc1_cr1,r10 | ||
750 | li r3,0x0003 | ||
751 | bl hsmc_cr_wait /* wait for op completion */ | ||
752 | cmpwi cr0,r3,0x0000 | ||
753 | bne hsmc1_err | ||
754 | |||
755 | /*--------------------------------------------------------------------+ | ||
756 | | Set HSMC1 Refresh Register | ||
757 | +--------------------------------------------------------------------*/ | ||
758 | lis r10,0x0FE1 | ||
759 | ori r10,r10,0x0000 | ||
760 | mtdcr hsmc1_crr,r10 | ||
761 | xor r3,r3,r3 | ||
762 | |||
763 | hsmc1_err: | ||
764 | mtlr r0 | ||
765 | blr | ||
766 | function_epilog(initb_hsmc1) | ||
767 | |||
768 | |||
769 | /****************************************************************************** | ||
770 | | | ||
771 | | Routine: INITB_CACHE | ||
772 | | | ||
773 | | Purpose: This routine will enable Data and Instruction Cache. | ||
774 | | The Data Cache is an 8K two-way set associative and the | ||
775 | | Instruction Cache is an 16K two-way set associative cache. | ||
776 | | | ||
777 | | Parameters: None. | ||
778 | | | ||
779 | | Returns: None. | ||
780 | | | ||
781 | ******************************************************************************/ | ||
782 | function_prolog(initb_cache) | ||
783 | mflr r0 /* Save return addr */ | ||
784 | |||
785 | bl initb_Dcache /* enable D-Cache */ | ||
786 | bl initb_Icache /* enable I-Cache */ | ||
787 | |||
788 | mtlr r0 | ||
789 | blr | ||
790 | function_epilog(initb_cache) | ||
791 | |||
792 | |||
793 | /****************************************************************************** | ||
794 | | | ||
795 | | Routine: INITB_DCACHE | ||
796 | | | ||
797 | | Purpose: This routine will invalidate all data in the Data Cache and | ||
798 | | then enable D-Cache. If cache is enabled already, the D-Cache | ||
799 | | will be flushed before the data is invalidated. | ||
800 | | | ||
801 | | Parameters: None. | ||
802 | | | ||
803 | | Returns: None. | ||
804 | | | ||
805 | ******************************************************************************/ | ||
806 | function_prolog(initb_Dcache) | ||
807 | /*--------------------------------------------------------------------+ | ||
808 | | Flush Data Cache if enabled | ||
809 | +--------------------------------------------------------------------*/ | ||
810 | mfdccr r10 /* r10 <- DCCR */ | ||
811 | isync /* ensure prev insts done */ | ||
812 | cmpwi r10,0x00 | ||
813 | beq ic_dcinv /* D-cache off, invalidate */ | ||
814 | |||
815 | /*--------------------------------------------------------------------+ | ||
816 | | Data Cache enabled, force known memory addresses to be Cached | ||
817 | +--------------------------------------------------------------------*/ | ||
818 | lis r10,HSMC0_BR0_VAL@h /* r10 <- first memory loc */ | ||
819 | andis. r10,r10,0xFFF0 | ||
820 | li r11,DCACHE_NLINES /* r11 <- # A-way addresses */ | ||
821 | addi r11,r11,DCACHE_NLINES /* r11 <- # B-way addresses */ | ||
822 | mtctr r11 /* set loop counter */ | ||
823 | |||
824 | ic_dcload: | ||
825 | lwz r12,0(r10) /* force cache of address */ | ||
826 | addi r10,r10,DCACHE_NBYTES /* r10 <- next memory loc */ | ||
827 | bdnz ic_dcload | ||
828 | sync /* ensure prev insts done */ | ||
829 | isync | ||
830 | |||
831 | /*--------------------------------------------------------------------+ | ||
832 | | Flush the known memory addresses from Cache | ||
833 | +--------------------------------------------------------------------*/ | ||
834 | lis r10,HSMC0_BR0_VAL@h /* r10 <- first memory loc */ | ||
835 | andis. r10,r10,0xFFF0 | ||
836 | mtctr r11 /* set loop counter */ | ||
837 | |||
838 | ic_dcflush: | ||
839 | dcbf 0,r10 /* flush D-cache line */ | ||
840 | addi r10,r10,DCACHE_NBYTES /* r10 <- next memory loc */ | ||
841 | bdnz ic_dcflush | ||
842 | sync /* ensure prev insts done */ | ||
843 | isync | ||
844 | |||
845 | /*--------------------------------------------------------------------+ | ||
846 | | Disable then invalidate Data Cache | ||
847 | +--------------------------------------------------------------------*/ | ||
848 | li r10,0 /* r10 <- 0 */ | ||
849 | mtdccr r10 /* disable the D-Cache */ | ||
850 | isync /* ensure prev insts done */ | ||
851 | |||
852 | ic_dcinv: | ||
853 | li r10,0 /* r10 <- line address */ | ||
854 | li r11,DCACHE_NLINES /* r11 <- # lines in cache */ | ||
855 | mtctr r11 /* set loop counter */ | ||
856 | |||
857 | ic_dcloop: | ||
858 | dccci 0,r10 /* invalidate A/B cache lns */ | ||
859 | addi r10,r10,DCACHE_NBYTES /* bump to next line */ | ||
860 | bdnz ic_dcloop | ||
861 | sync /* ensure prev insts done */ | ||
862 | isync | ||
863 | |||
864 | /*--------------------------------------------------------------------+ | ||
865 | | Enable Data Cache | ||
866 | +--------------------------------------------------------------------*/ | ||
867 | lis r10,DCACHE_ENABLE@h /* r10 <- D-cache enable msk*/ | ||
868 | ori r10,r10,DCACHE_ENABLE@l | ||
869 | mtdccr r10 | ||
870 | sync /* ensure prev insts done */ | ||
871 | isync | ||
872 | |||
873 | blr | ||
874 | function_epilog(initb_Dcache) | ||
875 | |||
876 | |||
877 | /****************************************************************************** | ||
878 | | | ||
879 | | Routine: INITB_ICACHE | ||
880 | | | ||
881 | | Purpose: This routine will invalidate all data in the Instruction | ||
882 | | Cache then enable I-Cache. | ||
883 | | | ||
884 | | Parameters: None. | ||
885 | | | ||
886 | | Returns: None. | ||
887 | | | ||
888 | ******************************************************************************/ | ||
889 | function_prolog(initb_Icache) | ||
890 | /*--------------------------------------------------------------------+ | ||
891 | | Invalidate Instruction Cache | ||
892 | +--------------------------------------------------------------------*/ | ||
893 | li r10,0 /* r10 <- lines address */ | ||
894 | iccci 0,r10 /* invalidate all I-cache */ | ||
895 | sync /* ensure prev insts done */ | ||
896 | isync | ||
897 | |||
898 | /*--------------------------------------------------------------------+ | ||
899 | | Enable Instruction Cache | ||
900 | +--------------------------------------------------------------------*/ | ||
901 | lis r10,ICACHE_ENABLE@h /* r10 <- I-cache enable msk*/ | ||
902 | ori r10,r10,ICACHE_ENABLE@l | ||
903 | mticcr r10 | ||
904 | sync /* ensure prev insts done */ | ||
905 | isync | ||
906 | |||
907 | blr | ||
908 | function_epilog(initb_Icache) | ||
909 | |||
910 | #if 0 | ||
911 | /****************************************************************************** | ||
912 | | | ||
913 | | Routine: INITB_GET_CSPD | ||
914 | | | ||
915 | | Purpose: Determine the CPU Core Speed. The 13.5 Mhz Time Base | ||
916 | | Counter (TBC) is used to measure a conditional branch | ||
917 | | instruction. | ||
918 | | | ||
919 | | Parameters: R3 = Address of Bus Speed | ||
920 | | R4 = Address of Core Speed | ||
921 | | | ||
922 | | Returns: (R3) = >0: Bus Speed. | ||
923 | | 0: Bus Speed not found in Look-Up Table. | ||
924 | | (R4) = >0: Core Speed. | ||
925 | | 0: Core Speed not found in Look-Up Table. | ||
926 | | | ||
927 | | Note: 1. This routine assumes the bdnz branch instruction takes | ||
928 | | two instruction cycles to complete. | ||
929 | | 2. This routine must be called before interrupts are enabled. | ||
930 | | | ||
931 | ******************************************************************************/ | ||
932 | function_prolog(initb_get_cspd) | ||
933 | mflr r0 /* Save return address */ | ||
934 | /*--------------------------------------------------------------------+ | ||
935 | | Set-up timed loop | ||
936 | +--------------------------------------------------------------------*/ | ||
937 | lis r9,gcs_time_loop@h /* r9 <- addr loop instr */ | ||
938 | ori r9,r9,gcs_time_loop@l | ||
939 | lis r10,GCS_LCNT@h /* r10 <- loop count */ | ||
940 | ori r10,r10,GCS_LCNT@l | ||
941 | mtctr r10 /* ctr <- loop count */ | ||
942 | lis r11,STB_TIMERS_TBC@h /* r11 <- TBC register addr */ | ||
943 | ori r11,r11,STB_TIMERS_TBC@l | ||
944 | li r12,0 /* r12 <- 0 */ | ||
945 | |||
946 | /*--------------------------------------------------------------------+ | ||
947 | | Cache timed-loop instruction | ||
948 | +--------------------------------------------------------------------*/ | ||
949 | icbt 0,r9 | ||
950 | sync | ||
951 | isync | ||
952 | |||
953 | /*--------------------------------------------------------------------+ | ||
954 | | Get number of 13.5 Mhz cycles to execute time-loop | ||
955 | +--------------------------------------------------------------------*/ | ||
956 | stw r12,0(r11) /* reset TBC */ | ||
957 | gcs_time_loop: | ||
958 | bdnz+ gcs_time_loop /* force branch pred taken */ | ||
959 | lwz r5,0(r11) /* r5 <- num 13.5 Mhz ticks */ | ||
960 | li r6,5 /* LUT based on 1/5th the...*/ | ||
961 | divw r5,r5,r6 /*..loop count used */ | ||
962 | sync | ||
963 | isync | ||
964 | |||
965 | /*--------------------------------------------------------------------+ | ||
966 | | Look-up core speed based on TBC value | ||
967 | +--------------------------------------------------------------------*/ | ||
968 | lis r6,gcs_lookup_table@h /* r6 <- pts at core spd LUT*/ | ||
969 | ori r6,r6,gcs_lookup_table@l | ||
970 | bl gcs_cspd_lookup /* find core speed in LUT */ | ||
971 | |||
972 | mtlr r0 /* set return address */ | ||
973 | blr | ||
974 | function_epilog(initb_get_cspd) | ||
975 | |||
976 | #endif | ||
977 | /*****************************************************************************+ | ||
978 | | XXXX XX XX XXXXXX XXXXXXX XXXXXX XX XX XX XXXX | ||
979 | | XX XXX XX X XX X XX X XX XX XXX XX XXXX XX | ||
980 | | XX XXXX XX XX XX X XX XX XXXX XX XX XX XX | ||
981 | | XX XX XXXX XX XXXX XXXXX XX XXXX XX XX XX | ||
982 | | XX XX XXX XX XX X XX XX XX XXX XXXXXX XX | ||
983 | | XX XX XX XX XX X XX XX XX XX XX XX XX XX | ||
984 | | XXXX XX XX XXXX XXXXXXX XXX XX XX XX XX XX XXXXXXX | ||
985 | +*****************************************************************************/ | ||
986 | /****************************************************************************** | ||
987 | | | ||
988 | | Routine: HSMC_CR_WAIT | ||
989 | | | ||
990 | | Purpose: Wait for the HSMC Control Register (bits 12-16) to be reset | ||
991 | | after an auto-refresh, pre-charge or program mode register | ||
992 | | command execution. | ||
993 | | | ||
994 | | Parameters: R3 = HSMC Control Register ID. | ||
995 | | 0: HSMC0 CR0 | ||
996 | | 1: HSMC0 CR1 | ||
997 | | 2: HSMC1 CR0 | ||
998 | | 3: HSMC1 CR1 | ||
999 | | | ||
1000 | | Returns: R3 = 0: Successful | ||
1001 | | -1: Unsuccessful | ||
1002 | | | ||
1003 | ******************************************************************************/ | ||
1004 | hsmc_cr_wait: | ||
1005 | |||
1006 | li r11,10 /* r11 <- retry counter */ | ||
1007 | mtctr r11 /* set retry counter */ | ||
1008 | mr r11,r3 /* r11 <- HSMC CR reg id */ | ||
1009 | |||
1010 | hsmc_cr_rep: | ||
1011 | bdz hsmc_cr_err /* branch if max retries hit*/ | ||
1012 | |||
1013 | /*--------------------------------------------------------------------+ | ||
1014 | | GET HSMCx_CRx value based on HSMC Control Register ID | ||
1015 | +--------------------------------------------------------------------*/ | ||
1016 | try_hsmc0_cr0: /* CHECK IF ID=HSMC0 CR0 REG*/ | ||
1017 | cmpwi cr0,r11,0x0000 | ||
1018 | bne cr0,try_hsmc0_cr1 | ||
1019 | mfdcr r10,hsmc0_cr0 /* r11 <- HSMC0 CR0 value */ | ||
1020 | b hsmc_cr_read | ||
1021 | |||
1022 | try_hsmc0_cr1: /* CHECK IF ID=HSMC0 CR1 REG*/ | ||
1023 | cmpwi cr0,r11,0x0001 | ||
1024 | bne cr0,try_hsmc1_cr0 | ||
1025 | mfdcr r10,hsmc0_cr1 /* r10 <- HSMC0 CR1 value */ | ||
1026 | b hsmc_cr_read | ||
1027 | |||
1028 | try_hsmc1_cr0: /* CHECK IF ID=HSMC1 CR0 REG*/ | ||
1029 | cmpwi cr0,r11,0x0002 | ||
1030 | bne cr0,try_hsmc1_cr1 | ||
1031 | mfdcr r10,hsmc1_cr0 /* r10 <- HSMC1 CR0 value */ | ||
1032 | b hsmc_cr_read | ||
1033 | |||
1034 | try_hsmc1_cr1: /* CHECK IF ID=HSMC1 CR1 REG*/ | ||
1035 | cmpwi cr0,r11,0x0003 | ||
1036 | bne cr0,hsmc_cr_err | ||
1037 | mfdcr r10,hsmc1_cr1 /* r10 <- HSMC1 CR1 value */ | ||
1038 | |||
1039 | /*--------------------------------------------------------------------+ | ||
1040 | | Check if HSMC CR register was reset after command execution | ||
1041 | +--------------------------------------------------------------------*/ | ||
1042 | hsmc_cr_read: | ||
1043 | lis r12,0x000F /* create "AND" mask */ | ||
1044 | ori r12,r12,0x8000 | ||
1045 | and. r10,r10,r12 /* r10 <- HSMC CR bits 12-16*/ | ||
1046 | bne cr0,hsmc_cr_rep /* wait for bits to reset */ | ||
1047 | li r3,0 /* set return code = success*/ | ||
1048 | b hsmc_cr_done | ||
1049 | |||
1050 | hsmc_cr_err: /* ERROR: SDRAM didn't reset*/ | ||
1051 | li r3,-1 /* set RC=unsuccessful */ | ||
1052 | |||
1053 | hsmc_cr_done: | ||
1054 | blr | ||
1055 | |||
1056 | #if 0 | ||
1057 | /****************************************************************************** | ||
1058 | | | ||
1059 | | Routine: GCS_CSPD_LOOKUP | ||
1060 | | | ||
1061 | | Purpose: Uses the number of 13.5 Mhz clock ticks found after executing | ||
1062 | | the branch instruction time loop to look-up the CPU Core Speed | ||
1063 | | in the Core Speed Look-up Table. | ||
1064 | | | ||
1065 | | Parameters: R3 = Address of Bus Speed | ||
1066 | | R4 = Address of Core Speed | ||
1067 | | R5 = Number of 13.5 Mhz clock ticks found in time loop. | ||
1068 | | R6 = Pointer to Core-Speed Look-Up Table | ||
1069 | | | ||
1070 | | Returns: (R3) = >0: Bus Speed. | ||
1071 | | 0: Bus Speed not found in Look-Up Table. | ||
1072 | | (R4) = >0: Core Speed. | ||
1073 | | 0: Core Speed not found in Look-Up Table. | ||
1074 | | | ||
1075 | | Note: Core Speed = Bus Speed * Mult Factor (1-4x). | ||
1076 | | | ||
1077 | ******************************************************************************/ | ||
1078 | gcs_cspd_lookup: | ||
1079 | |||
1080 | li r9,1 /* r9 <- core speed mult */ | ||
1081 | /*--------------------------------------------------------------------+ | ||
1082 | | Get theoritical number 13.5 Mhz ticks for a given Bus Speed from | ||
1083 | | Look-up Table. Check all mult factors to determine if calculated | ||
1084 | | value matches theoretical value (within a tolerance). | ||
1085 | +--------------------------------------------------------------------*/ | ||
1086 | gcs_cspd_loop: | ||
1087 | lwz r10,0(r6) /* r10 <- no. ticks from LUT*/ | ||
1088 | divw r10,r10,r9 /* r10 <- div mult (1-4x) */ | ||
1089 | subi r11,r10,GCS_CTICK_TOL /* r11 <- no. tks low range */ | ||
1090 | addi r12,r10,GCS_CTICK_TOL /* r12 <- no. tks high range*/ | ||
1091 | |||
1092 | cmpw cr0,r5,r11 /* calc value within range? */ | ||
1093 | blt gcs_cspd_retry /* less than low range */ | ||
1094 | cmpw cr0,r5,r12 | ||
1095 | bgt gcs_cspd_retry /* greater than high range */ | ||
1096 | b gcs_cspd_fnd /* calc value within range */ | ||
1097 | |||
1098 | /*--------------------------------------------------------------------+ | ||
1099 | | SO FAR CORE SPEED NOT FOUND: Check next mult factor | ||
1100 | +--------------------------------------------------------------------*/ | ||
1101 | gcs_cspd_retry: | ||
1102 | addi r9,r9,1 /* bump mult factor (1-4x) */ | ||
1103 | cmpwi cr0,r9,GCS_NMULT | ||
1104 | ble gcs_cspd_loop | ||
1105 | |||
1106 | /*--------------------------------------------------------------------+ | ||
1107 | | SO FAR CORE SPEED NOT FOUND: Point at next Bus Speed in LUT | ||
1108 | +--------------------------------------------------------------------*/ | ||
1109 | li r9,1 /* reset mult factor */ | ||
1110 | addi r6,r6,GCS_TROW_BYTES /* point at next table entry*/ | ||
1111 | lwz r10,0(r6) | ||
1112 | cmpwi cr0,r10,0 /* check for EOT flag */ | ||
1113 | bne gcs_cspd_loop | ||
1114 | |||
1115 | /*--------------------------------------------------------------------+ | ||
1116 | | COMPUTE CORE SPEED AND GET BUS SPEED FROM LOOK-UP TABLE | ||
1117 | +--------------------------------------------------------------------*/ | ||
1118 | gcs_cspd_fnd: | ||
1119 | lwz r5,4(r6) /* r5 <- Bus Speed in LUT */ | ||
1120 | mullw r6,r5,r9 /* r6 <- Core speed */ | ||
1121 | stw r5,0(r3) /* (r3) <- Bus Speed */ | ||
1122 | stw r6,0(r4) /* (r4) <- Core Speed */ | ||
1123 | |||
1124 | blr | ||
1125 | #endif | ||
diff --git a/arch/ppc/boot/simple/rw4/stb.h b/arch/ppc/boot/simple/rw4/stb.h new file mode 100644 index 000000000000..fd98ee0f843e --- /dev/null +++ b/arch/ppc/boot/simple/rw4/stb.h | |||
@@ -0,0 +1,239 @@ | |||
1 | /*----------------------------------------------------------------------------+ | ||
2 | | This source code has been made available to you by IBM on an AS-IS | ||
3 | | basis. Anyone receiving this source is licensed under IBM | ||
4 | | copyrights to use it in any way he or she deems fit, including | ||
5 | | copying it, modifying it, compiling it, and redistributing it either | ||
6 | | with or without modifications. No license under IBM patents or | ||
7 | | patent applications is to be implied by the copyright license. | ||
8 | | | ||
9 | | Any user of this software should understand that IBM cannot provide | ||
10 | | technical support for this software and will not be responsible for | ||
11 | | any consequences resulting from the use of this software. | ||
12 | | | ||
13 | | Any person who transfers this source code or any derivative work | ||
14 | | must include the IBM copyright notice, this paragraph, and the | ||
15 | | preceding two paragraphs in the transferred software. | ||
16 | | | ||
17 | | COPYRIGHT I B M CORPORATION 1999 | ||
18 | | LICENSED MATERIAL - PROGRAM PROPERTY OF I B M | ||
19 | +----------------------------------------------------------------------------*/ | ||
20 | /*----------------------------------------------------------------------------+ | ||
21 | | Author: Maciej P. Tyrlik | ||
22 | | Component: Include file. | ||
23 | | File: stb.h | ||
24 | | Purpose: Common Set-tob-box definitions. | ||
25 | | Changes: | ||
26 | | Date: Comment: | ||
27 | | ----- -------- | ||
28 | | 14-Jan-97 Created for ElPaso pass 1 MPT | ||
29 | | 13-May-97 Added function prototype and global variables MPT | ||
30 | | 08-Dec-98 Added RAW IR task information MPT | ||
31 | | 19-Jan-99 Port to Romeo MPT | ||
32 | | 19-May-00 Changed SDRAM to 32MB contiguous 0x1F000000 - 0x20FFFFFF RLB | ||
33 | +----------------------------------------------------------------------------*/ | ||
34 | |||
35 | #ifndef _stb_h_ | ||
36 | #define _stb_h_ | ||
37 | |||
38 | /*----------------------------------------------------------------------------+ | ||
39 | | Read/write from I/O macros. | ||
40 | +----------------------------------------------------------------------------*/ | ||
41 | #define inbyte(port) (*((unsigned char volatile *)(port))) | ||
42 | #define outbyte(port,data) *(unsigned char volatile *)(port)=\ | ||
43 | (unsigned char)(data) | ||
44 | |||
45 | #define inshort(port) (*((unsigned short volatile *)(port))) | ||
46 | #define outshort(port,data) *(unsigned short volatile *)(port)=\ | ||
47 | (unsigned short)(data) | ||
48 | |||
49 | #define inword(port) (*((unsigned long volatile *)(port))) | ||
50 | #define outword(port,data) *(unsigned long volatile *)(port)=\ | ||
51 | (unsigned long)(data) | ||
52 | |||
53 | /*----------------------------------------------------------------------------+ | ||
54 | | STB interrupts. | ||
55 | +----------------------------------------------------------------------------*/ | ||
56 | #define STB_XP_TP_INT 0 | ||
57 | #define STB_XP_APP_INT 1 | ||
58 | #define STB_AUD_INT 2 | ||
59 | #define STB_VID_INT 3 | ||
60 | #define STB_DMA0_INT 4 | ||
61 | #define STB_DMA1_INT 5 | ||
62 | #define STB_DMA2_INT 6 | ||
63 | #define STB_DMA3_INT 7 | ||
64 | #define STB_SCI_INT 8 | ||
65 | #define STB_I2C1_INT 9 | ||
66 | #define STB_I2C2_INT 10 | ||
67 | #define STB_GPT_PWM0 11 | ||
68 | #define STB_GPT_PWM1 12 | ||
69 | #define STB_SCP_INT 13 | ||
70 | #define STB_SSP_INT 14 | ||
71 | #define STB_GPT_PWM2 15 | ||
72 | #define STB_EXT5_INT 16 | ||
73 | #define STB_EXT6_INT 17 | ||
74 | #define STB_EXT7_INT 18 | ||
75 | #define STB_EXT8_INT 19 | ||
76 | #define STB_SCC_INT 20 | ||
77 | #define STB_SICC_RECV_INT 21 | ||
78 | #define STB_SICC_TRAN_INT 22 | ||
79 | #define STB_PPU_INT 23 | ||
80 | #define STB_DCRX_INT 24 | ||
81 | #define STB_EXT0_INT 25 | ||
82 | #define STB_EXT1_INT 26 | ||
83 | #define STB_EXT2_INT 27 | ||
84 | #define STB_EXT3_INT 28 | ||
85 | #define STB_EXT4_INT 29 | ||
86 | #define STB_REDWOOD_ENET_INT STB_EXT1_INT | ||
87 | |||
88 | /*----------------------------------------------------------------------------+ | ||
89 | | STB tasks, task stack sizes, and task priorities. The actual task priority | ||
90 | | is 1 more than the specified number since priority 0 is reserved (system | ||
91 | | internaly adds 1 to supplied priority number). | ||
92 | +----------------------------------------------------------------------------*/ | ||
93 | #define STB_IDLE_TASK_SS (5* 1024) | ||
94 | #define STB_IDLE_TASK_PRIO 0 | ||
95 | #define STB_LEDTEST_SS (2* 1024) | ||
96 | #define STB_LEDTEST_PRIO 0 | ||
97 | #define STB_CURSOR_TASK_SS (10* 1024) | ||
98 | #define STB_CURSOR_TASK_PRIO 7 | ||
99 | #define STB_MPEG_TASK_SS (10* 1024) | ||
100 | #define STB_MPEG_TASK_PRIO 9 | ||
101 | #define STB_DEMUX_TASK_SS (10* 1024) | ||
102 | #define STB_DEMUX_TASK_PRIO 20 | ||
103 | #define RAW_STB_IR_TASK_SS (10* 1024) | ||
104 | #define RAW_STB_IR_TASK_PRIO 20 | ||
105 | |||
106 | #define STB_SERIAL_ER_TASK_SS (10* 1024) | ||
107 | #define STB_SERIAL_ER_TASK_PRIO 1 | ||
108 | #define STB_CA_TASK_SS (10* 1024) | ||
109 | #define STB_CA_TASK_PRIO 8 | ||
110 | |||
111 | #define INIT_DEFAULT_VIDEO_SS (10* 1024) | ||
112 | #define INIT_DEFAULT_VIDEO_PRIO 8 | ||
113 | #define INIT_DEFAULT_SERVI_SS (10* 1024) | ||
114 | #define INIT_DEFAULT_SERVI_PRIO 8 | ||
115 | #define INIT_DEFAULT_POST_SS (10* 1024) | ||
116 | #define INIT_DEFAULT_POST_PRIO 8 | ||
117 | #define INIT_DEFAULT_INTER_SS (10* 1024) | ||
118 | #define INIT_DEFAULT_INTER_PRIO 8 | ||
119 | #define INIT_DEFAULT_BR_SS (10* 1024) | ||
120 | #define INIT_DEFAULT_BR_PRIO 8 | ||
121 | #define INITIAL_TASK_STACK_SIZE (32* 1024) | ||
122 | |||
123 | #ifdef VESTA | ||
124 | /*----------------------------------------------------------------------------+ | ||
125 | | Vesta Overall Address Map (all addresses are double mapped, bit 0 of the | ||
126 | | address is not decoded. Numbers below are dependent on board configuration. | ||
127 | | FLASH, SDRAM, DRAM numbers can be affected by actual board setup. | ||
128 | | | ||
129 | | FFE0,0000 - FFFF,FFFF FLASH | ||
130 | | F200,0000 - F210,FFFF FPGA logic | ||
131 | | Ethernet = F200,0000 | ||
132 | | LED Display = F200,0100 | ||
133 | | Xilinx #1 Regs = F204,0000 | ||
134 | | Xilinx #2 Regs = F208,0000 | ||
135 | | Spare = F20C,0000 | ||
136 | | IDE CS0 = F210,0000 | ||
137 | | F410,0000 - F410,FFFF IDE CS1 | ||
138 | | C000,0000 - C7FF,FFFF OBP | ||
139 | | C000,0000 - C000,0014 SICC (16550 + infra red) | ||
140 | | C001,0000 - C001,0018 PPU (Parallel Port) | ||
141 | | C002,0000 - C002,001B SC0 (Smart Card 0) | ||
142 | | C003,0000 - C003,000F I2C0 | ||
143 | | C004,0000 - C004,0009 SCC (16550 UART) | ||
144 | | C005,0000 - C005,0124 GPT (Timers) | ||
145 | | C006,0000 - C006,0058 GPIO0 | ||
146 | | C007,0000 - C007,001b SC1 (Smart Card 1) | ||
147 | | C008,0000 - C008,FFFF Unused | ||
148 | | C009,0000 - C009,FFFF Unused | ||
149 | | C00A,0000 - C00A,FFFF Unused | ||
150 | | C00B,0000 - C00B,000F I2C1 | ||
151 | | C00C,0000 - C00C,0006 SCP | ||
152 | | C00D,0000 - C00D,0010 SSP | ||
153 | | A000,0000 - A0FF,FFFF SDRAM1 (16M) | ||
154 | | 0000,0000 - 00FF,FFFF SDRAM0 (16M) | ||
155 | +----------------------------------------------------------------------------*/ | ||
156 | #define STB_FLASH_BASE_ADDRESS 0xFFE00000 | ||
157 | #define STB_FPGA_BASE_ADDRESS 0xF2000000 | ||
158 | #define STB_SICC_BASE_ADDRESS 0xC0000000 | ||
159 | #define STB_PPU_BASE_ADDR 0xC0010000 | ||
160 | #define STB_SC0_BASE_ADDRESS 0xC0020000 | ||
161 | #define STB_I2C1_BASE_ADDRESS 0xC0030000 | ||
162 | #define STB_SCC_BASE_ADDRESS 0xC0040000 | ||
163 | #define STB_TIMERS_BASE_ADDRESS 0xC0050000 | ||
164 | #define STB_GPIO0_BASE_ADDRESS 0xC0060000 | ||
165 | #define STB_SC1_BASE_ADDRESS 0xC0070000 | ||
166 | #define STB_I2C2_BASE_ADDRESS 0xC00B0000 | ||
167 | #define STB_SCP_BASE_ADDRESS 0xC00C0000 | ||
168 | #define STB_SSP_BASE_ADDRESS 0xC00D0000 | ||
169 | /*----------------------------------------------------------------------------+ | ||
170 | |The following are used by the IBM RTOS SW. | ||
171 | |15-May-00 Changed these values to reflect movement of base addresses in | ||
172 | |order to support 32MB of contiguous SDRAM space. | ||
173 | |Points to the cacheable region since these values are used in IBM RTOS | ||
174 | |to establish the vector address. | ||
175 | +----------------------------------------------------------------------------*/ | ||
176 | #define STB_SDRAM1_BASE_ADDRESS 0x20000000 | ||
177 | #define STB_SDRAM1_SIZE 0x01000000 | ||
178 | #define STB_SDRAM0_BASE_ADDRESS 0x1F000000 | ||
179 | #define STB_SDRAM0_SIZE 0x01000000 | ||
180 | |||
181 | #else | ||
182 | /*----------------------------------------------------------------------------+ | ||
183 | | ElPaso Overall Address Map (all addresses are double mapped, bit 0 of the | ||
184 | | address is not decoded. Numbers below are dependent on board configuration. | ||
185 | | FLASH, SDRAM, DRAM numbers can be affected by actual board setup. OPB | ||
186 | | devices are inside the ElPaso chip. | ||
187 | | FFE0,0000 - FFFF,FFFF FLASH | ||
188 | | F144,0000 - F104,FFFF FPGA logic | ||
189 | | F140,0000 - F100,0000 ethernet (through FPGA logic) | ||
190 | | C000,0000 - C7FF,FFFF OBP | ||
191 | | C000,0000 - C000,0014 SICC (16550+ infra red) | ||
192 | | C001,0000 - C001,0016 PPU (parallel port) | ||
193 | | C002,0000 - C002,001B SC (smart card) | ||
194 | | C003,0000 - C003,000F I2C 1 | ||
195 | | C004,0000 - C004,0009 SCC (16550 UART) | ||
196 | | C005,0000 - C005,0124 Timers | ||
197 | | C006,0000 - C006,0058 GPIO0 | ||
198 | | C007,0000 - C007,0058 GPIO1 | ||
199 | | C008,0000 - C008,0058 GPIO2 | ||
200 | | C009,0000 - C009,0058 GPIO3 | ||
201 | | C00A,0000 - C00A,0058 GPIO4 | ||
202 | | C00B,0000 - C00B,000F I2C 2 | ||
203 | | C00C,0000 - C00C,0006 SCP | ||
204 | | C00D,0000 - C00D,0006 SSP | ||
205 | | A000,0000 - A0FF,FFFF SDRAM 16M | ||
206 | | 0000,0000 - 00FF,FFFF DRAM 16M | ||
207 | +----------------------------------------------------------------------------*/ | ||
208 | #define STB_FLASH_BASE_ADDRESS 0xFFE00000 | ||
209 | #define STB_FPGA_BASE_ADDRESS 0xF1440000 | ||
210 | #define STB_ENET_BASE_ADDRESS 0xF1400000 | ||
211 | #define STB_SICC_BASE_ADDRESS 0xC0000000 | ||
212 | #define STB_PPU_BASE_ADDR 0xC0010000 | ||
213 | #define STB_SC_BASE_ADDRESS 0xC0020000 | ||
214 | #define STB_I2C1_BASE_ADDRESS 0xC0030000 | ||
215 | #define STB_SCC_BASE_ADDRESS 0xC0040000 | ||
216 | #define STB_TIMERS_BASE_ADDRESS 0xC0050000 | ||
217 | #define STB_GPIO0_BASE_ADDRESS 0xC0060000 | ||
218 | #define STB_GPIO1_BASE_ADDRESS 0xC0070000 | ||
219 | #define STB_GPIO2_BASE_ADDRESS 0xC0080000 | ||
220 | #define STB_GPIO3_BASE_ADDRESS 0xC0090000 | ||
221 | #define STB_GPIO4_BASE_ADDRESS 0xC00A0000 | ||
222 | #define STB_I2C2_BASE_ADDRESS 0xC00B0000 | ||
223 | #define STB_SCP_BASE_ADDRESS 0xC00C0000 | ||
224 | #define STB_SSP_BASE_ADDRESS 0xC00D0000 | ||
225 | #define STB_SDRAM_BASE_ADDRESS 0xA0000000 | ||
226 | #endif | ||
227 | |||
228 | /*----------------------------------------------------------------------------+ | ||
229 | | Other common defines. | ||
230 | +----------------------------------------------------------------------------*/ | ||
231 | #ifndef TRUE | ||
232 | #define TRUE 1 | ||
233 | #endif | ||
234 | |||
235 | #ifndef FALSE | ||
236 | #define FALSE 0 | ||
237 | #endif | ||
238 | |||
239 | #endif /* _stb_h_ */ | ||