Tue Apr 26 08:08:40 2011 UTC ()
Priority of QNAP board detection was still too high. It should be lowest,
because a Realtek chip at pci device 15 is used on several boards. Now
NH230/All6250 detection should work again.


(phx)
diff -r1.16 -r1.17 src/sys/arch/sandpoint/stand/altboot/brdsetup.c

cvs diff -r1.16 -r1.17 src/sys/arch/sandpoint/stand/altboot/brdsetup.c (switch to unified diff)

--- src/sys/arch/sandpoint/stand/altboot/brdsetup.c 2011/04/25 18:28:47 1.16
+++ src/sys/arch/sandpoint/stand/altboot/brdsetup.c 2011/04/26 08:08:39 1.17
@@ -1,1060 +1,1060 @@ @@ -1,1060 +1,1060 @@
1/* $NetBSD: brdsetup.c,v 1.16 2011/04/25 18:28:47 phx Exp $ */ 1/* $NetBSD: brdsetup.c,v 1.17 2011/04/26 08:08:39 phx Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Tohru Nishimura. 8 * by Tohru Nishimura.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33 33
34#include <powerpc/psl.h> 34#include <powerpc/psl.h>
35#include <powerpc/oea/spr.h> 35#include <powerpc/oea/spr.h>
36 36
37#include <lib/libsa/stand.h> 37#include <lib/libsa/stand.h>
38#include <lib/libsa/net.h> 38#include <lib/libsa/net.h>
39#include <lib/libkern/libkern.h> 39#include <lib/libkern/libkern.h>
40 40
41#include <machine/bootinfo.h> 41#include <machine/bootinfo.h>
42 42
43#include "globals.h" 43#include "globals.h"
44 44
45#define BRD_DECL(xxx) \ 45#define BRD_DECL(xxx) \
46 void xxx ## setup(struct brdprop *); \ 46 void xxx ## setup(struct brdprop *); \
47 void xxx ## brdfix(struct brdprop *); \ 47 void xxx ## brdfix(struct brdprop *); \
48 void xxx ## pcifix(struct brdprop *); \ 48 void xxx ## pcifix(struct brdprop *); \
49 void xxx ## reset(void) 49 void xxx ## reset(void)
50 50
51BRD_DECL(mot); 51BRD_DECL(mot);
52BRD_DECL(enc); 52BRD_DECL(enc);
53BRD_DECL(kuro); 53BRD_DECL(kuro);
54BRD_DECL(syno); 54BRD_DECL(syno);
55BRD_DECL(qnap); 55BRD_DECL(qnap);
56BRD_DECL(iomega); 56BRD_DECL(iomega);
57BRD_DECL(dlink); 57BRD_DECL(dlink);
58BRD_DECL(nhnas); 58BRD_DECL(nhnas);
59 59
60static struct brdprop brdlist[] = { 60static struct brdprop brdlist[] = {
61 { 61 {
62 "sandpoint", 62 "sandpoint",
63 "Sandpoint X3", 63 "Sandpoint X3",
64 BRD_SANDPOINTX3, 64 BRD_SANDPOINTX3,
65 0, 65 0,
66 "com", 0x3f8, 115200, 66 "com", 0x3f8, 115200,
67 motsetup, motbrdfix, motpcifix, NULL }, 67 motsetup, motbrdfix, motpcifix, NULL },
68 { 68 {
69 "encpp1", 69 "encpp1",
70 "EnCore PP1", 70 "EnCore PP1",
71 BRD_ENCOREPP1, 71 BRD_ENCOREPP1,
72 0, 72 0,
73 "com", 0x3f8, 115200, 73 "com", 0x3f8, 115200,
74 encsetup, encbrdfix, encpcifix, NULL }, 74 encsetup, encbrdfix, encpcifix, NULL },
75 { 75 {
76 "kurobox", 76 "kurobox",
77 "KuroBox", 77 "KuroBox",
78 BRD_KUROBOX, 78 BRD_KUROBOX,
79 32768000, 79 32768000,
80 "eumb", 0x4600, 57600, 80 "eumb", 0x4600, 57600,
81 kurosetup, kurobrdfix, NULL, NULL }, 81 kurosetup, kurobrdfix, NULL, NULL },
82 { 82 {
83 "synology", 83 "synology",
84 "Synology DS", 84 "Synology DS",
85 BRD_SYNOLOGY, 85 BRD_SYNOLOGY,
86 33164691, /* from Synology/Linux source */ 86 33164691, /* from Synology/Linux source */
87 /* XXX should be 33165343 for the CS-406 */ 87 /* XXX should be 33165343 for the CS-406 */
88 "eumb", 0x4500, 115200, 88 "eumb", 0x4500, 115200,
89 NULL, synobrdfix, NULL, synoreset }, 89 NULL, synobrdfix, NULL, synoreset },
90 { 90 {
91 "qnap", 91 "qnap",
92 "QNAP TS", 92 "QNAP TS",
93 BRD_QNAPTS, 93 BRD_QNAPTS,
94 33164691, /* Linux source says 33000000, but the Synology */ 94 33164691, /* Linux source says 33000000, but the Synology */
95 /* clock value delivers a much better precision. */ 95 /* clock value delivers a much better precision. */
96 "eumb", 0x4500, 115200, 96 "eumb", 0x4500, 115200,
97 NULL, qnapbrdfix, NULL, qnapreset }, 97 NULL, qnapbrdfix, NULL, qnapreset },
98 { 98 {
99 "iomega", 99 "iomega",
100 "IOMEGA StorCenter G2", 100 "IOMEGA StorCenter G2",
101 BRD_STORCENTER, 101 BRD_STORCENTER,
102 0, 102 0,
103 "eumb", 0x4500, 115200, 103 "eumb", 0x4500, 115200,
104 NULL, iomegabrdfix, NULL, NULL }, 104 NULL, iomegabrdfix, NULL, NULL },
105 { 105 {
106 "dlink", 106 "dlink",
107 "D-Link DSM-G600", 107 "D-Link DSM-G600",
108 BRD_DLINKDSM, 108 BRD_DLINKDSM,
109 33000000, 109 33000000,
110 "eumb", 0x4500, 9600, 110 "eumb", 0x4500, 9600,
111 NULL, dlinkbrdfix, NULL, NULL }, 111 NULL, dlinkbrdfix, NULL, NULL },
112 { 112 {
113 "nhnas", 113 "nhnas",
114 "Netronics NH230/231", 114 "Netronics NH230/231",
115 BRD_NH230NAS, 115 BRD_NH230NAS,
116 0, 116 0,
117 "eumb", 0x4500, 9600, 117 "eumb", 0x4500, 9600,
118 NULL, nhnasbrdfix, NULL, NULL }, 118 NULL, nhnasbrdfix, NULL, NULL },
119 { 119 {
120 "unknown", 120 "unknown",
121 "Unknown board", 121 "Unknown board",
122 BRD_UNKNOWN, 122 BRD_UNKNOWN,
123 0, 123 0,
124 "eumb", 0x4500, 115200, 124 "eumb", 0x4500, 115200,
125 NULL, NULL, NULL, NULL }, /* must be the last */ 125 NULL, NULL, NULL, NULL }, /* must be the last */
126}; 126};
127 127
128static struct brdprop *brdprop; 128static struct brdprop *brdprop;
129static uint32_t ticks_per_sec, ns_per_tick; 129static uint32_t ticks_per_sec, ns_per_tick;
130 130
131static void brdfixup(void); 131static void brdfixup(void);
132static void setup(void); 132static void setup(void);
133static inline uint32_t mfmsr(void); 133static inline uint32_t mfmsr(void);
134static inline void mtmsr(uint32_t); 134static inline void mtmsr(uint32_t);
135static inline uint32_t cputype(void); 135static inline uint32_t cputype(void);
136static inline u_quad_t mftb(void); 136static inline u_quad_t mftb(void);
137static void init_uart(unsigned, unsigned, uint8_t); 137static void init_uart(unsigned, unsigned, uint8_t);
138static void send_sat(char *); 138static void send_sat(char *);
139 139
140const unsigned dcache_line_size = 32; /* 32B linesize */ 140const unsigned dcache_line_size = 32; /* 32B linesize */
141const unsigned dcache_range_size = 4 * 1024; /* 16KB / 4-way */ 141const unsigned dcache_range_size = 4 * 1024; /* 16KB / 4-way */
142 142
143unsigned uart1base; /* console */ 143unsigned uart1base; /* console */
144unsigned uart2base; /* optional satellite processor */ 144unsigned uart2base; /* optional satellite processor */
145#define RBR 0 145#define RBR 0
146#define THR 0 146#define THR 0
147#define DLB 0 147#define DLB 0
148#define DMB 1 148#define DMB 1
149#define IER 1 149#define IER 1
150#define FCR 2 150#define FCR 2
151#define LCR 3 151#define LCR 3
152#define LCR_DLAB 0x80 152#define LCR_DLAB 0x80
153#define LCR_PEVEN 0x18 153#define LCR_PEVEN 0x18
154#define LCR_PNONE 0x00 154#define LCR_PNONE 0x00
155#define LCR_8BITS 0x03 155#define LCR_8BITS 0x03
156#define MCR 4 156#define MCR 4
157#define MCR_RTS 0x02 157#define MCR_RTS 0x02
158#define MCR_DTR 0x01 158#define MCR_DTR 0x01
159#define LSR 5 159#define LSR 5
160#define LSR_THRE 0x20 160#define LSR_THRE 0x20
161#define LSR_DRDY 0x01 161#define LSR_DRDY 0x01
162#define DCR 0x11 162#define DCR 0x11
163#define UART_READ(base, r) *(volatile char *)(base + (r)) 163#define UART_READ(base, r) *(volatile char *)(base + (r))
164#define UART_WRITE(base, r, v) *(volatile char *)(base + (r)) = (v) 164#define UART_WRITE(base, r, v) *(volatile char *)(base + (r)) = (v)
165 165
166void brdsetup(void); /* called by entry.S */ 166void brdsetup(void); /* called by entry.S */
167 167
168void 168void
169brdsetup(void) 169brdsetup(void)
170{ 170{
171 static uint8_t pci_to_memclk[] = { 171 static uint8_t pci_to_memclk[] = {
172 30, 30, 10, 10, 20, 10, 10, 10, 172 30, 30, 10, 10, 20, 10, 10, 10,
173 10, 20, 20, 15, 20, 15, 20, 30, 173 10, 20, 20, 15, 20, 15, 20, 30,
174 30, 40, 15, 40, 20, 25, 20, 40, 174 30, 40, 15, 40, 20, 25, 20, 40,
175 25, 20, 10, 20, 15, 15, 20, 00 175 25, 20, 10, 20, 15, 15, 20, 00
176 }; 176 };
177 static uint8_t mem_to_cpuclk[] = { 177 static uint8_t mem_to_cpuclk[] = {
178 25, 30, 45, 20, 20, 00, 10, 30, 178 25, 30, 45, 20, 20, 00, 10, 30,
179 30, 20, 45, 30, 25, 35, 30, 35, 179 30, 20, 45, 30, 25, 35, 30, 35,
180 20, 25, 20, 30, 35, 40, 40, 20, 180 20, 25, 20, 30, 35, 40, 40, 20,
181 30, 25, 40, 30, 30, 25, 35, 00 181 30, 25, 40, 30, 30, 25, 35, 00
182 }; 182 };
183 char *consname; 183 char *consname;
184 int consport; 184 int consport;
185 uint32_t extclk; 185 uint32_t extclk;
186 unsigned pchb, pcib, dev11, dev13, dev15, dev16, val; 186 unsigned pchb, pcib, dev11, dev13, dev15, dev16, val;
187 extern struct btinfo_memory bi_mem; 187 extern struct btinfo_memory bi_mem;
188 extern struct btinfo_console bi_cons; 188 extern struct btinfo_console bi_cons;
189 extern struct btinfo_clock bi_clk; 189 extern struct btinfo_clock bi_clk;
190 extern struct btinfo_prodfamily bi_fam; 190 extern struct btinfo_prodfamily bi_fam;
191 191
192 /* 192 /*
193 * CHRP specification "Map-B" BAT012 layout 193 * CHRP specification "Map-B" BAT012 layout
194 * BAT0 0000-0000 (256MB) SDRAM 194 * BAT0 0000-0000 (256MB) SDRAM
195 * BAT1 8000-0000 (256MB) PCI mem space 195 * BAT1 8000-0000 (256MB) PCI mem space
196 * BAT2 fc00-0000 (64MB) EUMB, PCI I/O space, misc devs, flash 196 * BAT2 fc00-0000 (64MB) EUMB, PCI I/O space, misc devs, flash
197 * 197 *
198 * EUMBBAR is at fc00-0000. 198 * EUMBBAR is at fc00-0000.
199 */ 199 */
200 pchb = pcimaketag(0, 0, 0); 200 pchb = pcimaketag(0, 0, 0);
201 pcicfgwrite(pchb, 0x78, 0xfc000000); 201 pcicfgwrite(pchb, 0x78, 0xfc000000);
202 202
203 brdtype = BRD_UNKNOWN; 203 brdtype = BRD_UNKNOWN;
204 extclk = EXT_CLK_FREQ; /* usually 33MHz */ 204 extclk = EXT_CLK_FREQ; /* usually 33MHz */
205 busclock = 0; 205 busclock = 0;
206 206
207 dev11 = pcimaketag(0, 11, 0); 207 dev11 = pcimaketag(0, 11, 0);
208 dev13 = pcimaketag(0, 13, 0); 208 dev13 = pcimaketag(0, 13, 0);
209 dev15 = pcimaketag(0, 15, 0); 209 dev15 = pcimaketag(0, 15, 0);
210 dev16 = pcimaketag(0, 16, 0); 210 dev16 = pcimaketag(0, 16, 0);
211 211
212 if (pcifinddev(0x10ad, 0x0565, &pcib) == 0) { 212 if (pcifinddev(0x10ad, 0x0565, &pcib) == 0) {
213 /* WinBond 553 southbridge at dev 11 */ 213 /* WinBond 553 southbridge at dev 11 */
214 brdtype = BRD_SANDPOINTX3; 214 brdtype = BRD_SANDPOINTX3;
215 } 215 }
216 else if (pcifinddev(0x1106, 0x0686, &pcib) == 0) { 216 else if (pcifinddev(0x1106, 0x0686, &pcib) == 0) {
217 /* VIA 686B southbridge at dev 22 */ 217 /* VIA 686B southbridge at dev 22 */
218 brdtype = BRD_ENCOREPP1; 218 brdtype = BRD_ENCOREPP1;
219 } 219 }
220 else if (PCI_CLASS(pcicfgread(dev11, PCI_CLASS_REG)) == PCI_CLASS_ETH) { 220 else if (PCI_CLASS(pcicfgread(dev11, PCI_CLASS_REG)) == PCI_CLASS_ETH) {
221 /* ADMtek AN985 (tlp) or RealTek 8169S (re) at dev 11 */ 221 /* ADMtek AN985 (tlp) or RealTek 8169S (re) at dev 11 */
222 brdtype = BRD_KUROBOX; 222 brdtype = BRD_KUROBOX;
223 } 223 }
224 else if (PCI_VENDOR(pcicfgread(dev15, PCI_ID_REG)) == 0x11ab) { 224 else if (PCI_VENDOR(pcicfgread(dev15, PCI_ID_REG)) == 0x11ab) {
225 /* SKnet/Marvell (sk) at dev 15 */ 225 /* SKnet/Marvell (sk) at dev 15 */
226 brdtype = BRD_SYNOLOGY; 226 brdtype = BRD_SYNOLOGY;
227 } 227 }
228 else if (PCI_VENDOR(pcicfgread(dev13, PCI_ID_REG)) == 0x1106) { 228 else if (PCI_VENDOR(pcicfgread(dev13, PCI_ID_REG)) == 0x1106) {
229 /* VIA 6410 (viaide) at dev 13 */ 229 /* VIA 6410 (viaide) at dev 13 */
230 brdtype = BRD_STORCENTER; 230 brdtype = BRD_STORCENTER;
231 } 231 }
232 else if (PCI_VENDOR(pcicfgread(dev15, PCI_ID_REG)) == 0x8086 
233 || PCI_VENDOR(pcicfgread(dev15, PCI_ID_REG)) == 0x10ec) { 
234 /* Intel (wm) or RealTek (re) at dev 15 */ 
235 brdtype = BRD_QNAPTS; 
236 } 
237 else if (PCI_VENDOR(pcicfgread(dev16, PCI_ID_REG)) == 0x1191) { 232 else if (PCI_VENDOR(pcicfgread(dev16, PCI_ID_REG)) == 0x1191) {
238 /* ACARD ATP865 (acardide) at dev 16 */ 233 /* ACARD ATP865 (acardide) at dev 16 */
239 brdtype = BRD_DLINKDSM; 234 brdtype = BRD_DLINKDSM;
240 } 235 }
241 else if (PCI_VENDOR(pcicfgread(dev16, PCI_ID_REG)) == 0x1283 236 else if (PCI_VENDOR(pcicfgread(dev16, PCI_ID_REG)) == 0x1283
242 || PCI_VENDOR(pcicfgread(dev16, PCI_ID_REG)) == 0x1095) { 237 || PCI_VENDOR(pcicfgread(dev16, PCI_ID_REG)) == 0x1095) {
243 /* ITE (iteide) or SiI (satalink) at dev 16 */ 238 /* ITE (iteide) or SiI (satalink) at dev 16 */
244 brdtype = BRD_NH230NAS; 239 brdtype = BRD_NH230NAS;
245 } 240 }
 241 else if (PCI_VENDOR(pcicfgread(dev15, PCI_ID_REG)) == 0x8086
 242 || PCI_VENDOR(pcicfgread(dev15, PCI_ID_REG)) == 0x10ec) {
 243 /* Intel (wm) or RealTek (re) at dev 15 */
 244 brdtype = BRD_QNAPTS;
 245 }
246 246
247 brdprop = brd_lookup(brdtype); 247 brdprop = brd_lookup(brdtype);
248 248
249 /* brd dependent adjustments */ 249 /* brd dependent adjustments */
250 setup(); 250 setup();
251 251
252 /* determine clock frequencies */ 252 /* determine clock frequencies */
253 if (brdprop->extclk != 0) 253 if (brdprop->extclk != 0)
254 extclk = brdprop->extclk; 254 extclk = brdprop->extclk;
255 if (busclock == 0) { 255 if (busclock == 0) {
256 if (cputype() == MPC8245) { 256 if (cputype() == MPC8245) {
257 /* PLL_CFG from PCI host bridge register 0xe2 */ 257 /* PLL_CFG from PCI host bridge register 0xe2 */
258 val = pcicfgread(pchb, 0xe0); 258 val = pcicfgread(pchb, 0xe0);
259 busclock = (extclk * 259 busclock = (extclk *
260 pci_to_memclk[(val >> 19) & 0x1f] + 10) / 10; 260 pci_to_memclk[(val >> 19) & 0x1f] + 10) / 10;
261 /* PLLRATIO from HID1 */ 261 /* PLLRATIO from HID1 */
262 asm volatile ("mfspr %0,1009" : "=r"(val)); 262 asm volatile ("mfspr %0,1009" : "=r"(val));
263 cpuclock = ((uint64_t)busclock * 263 cpuclock = ((uint64_t)busclock *
264 mem_to_cpuclk[val >> 27] + 10) / 10; 264 mem_to_cpuclk[val >> 27] + 10) / 10;
265 } else 265 } else
266 busclock = 100000000; /* 100MHz bus clock default */ 266 busclock = 100000000; /* 100MHz bus clock default */
267 } 267 }
268 ticks_per_sec = busclock >> 2; 268 ticks_per_sec = busclock >> 2;
269 ns_per_tick = 1000000000 / ticks_per_sec; 269 ns_per_tick = 1000000000 / ticks_per_sec;
270 270
271 /* now prepare serial console */ 271 /* now prepare serial console */
272 consname = brdprop->consname; 272 consname = brdprop->consname;
273 consport = brdprop->consport; 273 consport = brdprop->consport;
274 if (strcmp(consname, "eumb") == 0) { 274 if (strcmp(consname, "eumb") == 0) {
275 uart1base = 0xfc000000 + consport; /* 0x4500, 0x4600 */ 275 uart1base = 0xfc000000 + consport; /* 0x4500, 0x4600 */
276 UART_WRITE(uart1base, DCR, 0x01); /* enable DUART mode */ 276 UART_WRITE(uart1base, DCR, 0x01); /* enable DUART mode */
277 uart2base = uart1base ^ 0x0300; 277 uart2base = uart1base ^ 0x0300;
278 } else 278 } else
279 uart1base = 0xfe000000 + consport; /* 0x3f8, 0x2f8 */ 279 uart1base = 0xfe000000 + consport; /* 0x3f8, 0x2f8 */
280 280
281 /* more brd adjustments */ 281 /* more brd adjustments */
282 brdfixup(); 282 brdfixup();
283 283
284 bi_mem.memsize = mpc107memsize(); 284 bi_mem.memsize = mpc107memsize();
285 snprintf(bi_cons.devname, sizeof(bi_cons.devname), consname); 285 snprintf(bi_cons.devname, sizeof(bi_cons.devname), consname);
286 bi_cons.addr = consport; 286 bi_cons.addr = consport;
287 bi_cons.speed = brdprop->consspeed; 287 bi_cons.speed = brdprop->consspeed;
288 bi_clk.ticks_per_sec = ticks_per_sec; 288 bi_clk.ticks_per_sec = ticks_per_sec;
289 snprintf(bi_fam.name, sizeof(bi_fam.name), brdprop->family); 289 snprintf(bi_fam.name, sizeof(bi_fam.name), brdprop->family);
290} 290}
291 291
292struct brdprop * 292struct brdprop *
293brd_lookup(int brd) 293brd_lookup(int brd)
294{ 294{
295 u_int i; 295 u_int i;
296 296
297 for (i = 0; i < sizeof(brdlist)/sizeof(brdlist[0]); i++) { 297 for (i = 0; i < sizeof(brdlist)/sizeof(brdlist[0]); i++) {
298 if (brdlist[i].brdtype == brd) 298 if (brdlist[i].brdtype == brd)
299 return &brdlist[i]; 299 return &brdlist[i];
300 } 300 }
301 return &brdlist[i - 1]; 301 return &brdlist[i - 1];
302} 302}
303 303
304static void 304static void
305setup() 305setup()
306{ 306{
307 307
308 if (brdprop->setup == NULL) 308 if (brdprop->setup == NULL)
309 return; 309 return;
310 (*brdprop->setup)(brdprop); 310 (*brdprop->setup)(brdprop);
311} 311}
312 312
313static void 313static void
314brdfixup() 314brdfixup()
315{ 315{
316 316
317 if (brdprop->brdfix == NULL) 317 if (brdprop->brdfix == NULL)
318 return; 318 return;
319 (*brdprop->brdfix)(brdprop); 319 (*brdprop->brdfix)(brdprop);
320} 320}
321 321
322void 322void
323pcifixup() 323pcifixup()
324{ 324{
325 325
326 if (brdprop->pcifix == NULL) 326 if (brdprop->pcifix == NULL)
327 return; 327 return;
328 (*brdprop->pcifix)(brdprop); 328 (*brdprop->pcifix)(brdprop);
329} 329}
330 330
331void 331void
332encsetup(struct brdprop *brd) 332encsetup(struct brdprop *brd)
333{ 333{
334 334
335#ifdef COSNAME 335#ifdef COSNAME
336 brd->consname = CONSNAME; 336 brd->consname = CONSNAME;
337#endif 337#endif
338#ifdef CONSPORT 338#ifdef CONSPORT
339 brd->consport = CONSPORT; 339 brd->consport = CONSPORT;
340#endif 340#endif
341#ifdef CONSSPEED 341#ifdef CONSSPEED
342 brd->consspeed = CONSSPEED; 342 brd->consspeed = CONSSPEED;
343#endif 343#endif
344} 344}
345 345
346void 346void
347encbrdfix(struct brdprop *brd) 347encbrdfix(struct brdprop *brd)
348{ 348{
349 unsigned ac97, ide, pcib, pmgt, usb12, usb34, val; 349 unsigned ac97, ide, pcib, pmgt, usb12, usb34, val;
350 350
351/* 351/*
352 * VIA82C686B Southbridge 352 * VIA82C686B Southbridge
353 * 0.22.0 1106.0686 PCI-ISA bridge 353 * 0.22.0 1106.0686 PCI-ISA bridge
354 * 0.22.1 1106.0571 IDE (viaide) 354 * 0.22.1 1106.0571 IDE (viaide)
355 * 0.22.2 1106.3038 USB 0/1 (uhci) 355 * 0.22.2 1106.3038 USB 0/1 (uhci)
356 * 0.22.3 1106.3038 USB 2/3 (uhci) 356 * 0.22.3 1106.3038 USB 2/3 (uhci)
357 * 0.22.4 1106.3057 power management 357 * 0.22.4 1106.3057 power management
358 * 0.22.5 1106.3058 AC97 (auvia) 358 * 0.22.5 1106.3058 AC97 (auvia)
359 */ 359 */
360 pcib = pcimaketag(0, 22, 0); 360 pcib = pcimaketag(0, 22, 0);
361 ide = pcimaketag(0, 22, 1); 361 ide = pcimaketag(0, 22, 1);
362 usb12 = pcimaketag(0, 22, 2); 362 usb12 = pcimaketag(0, 22, 2);
363 usb34 = pcimaketag(0, 22, 3); 363 usb34 = pcimaketag(0, 22, 3);
364 pmgt = pcimaketag(0, 22, 4); 364 pmgt = pcimaketag(0, 22, 4);
365 ac97 = pcimaketag(0, 22, 5); 365 ac97 = pcimaketag(0, 22, 5);
366 366
367#define CFG(i,v) do { \ 367#define CFG(i,v) do { \
368 *(volatile unsigned char *)(0xfe000000 + 0x3f0) = (i); \ 368 *(volatile unsigned char *)(0xfe000000 + 0x3f0) = (i); \
369 *(volatile unsigned char *)(0xfe000000 + 0x3f1) = (v); \ 369 *(volatile unsigned char *)(0xfe000000 + 0x3f1) = (v); \
370 } while (0) 370 } while (0)
371 val = pcicfgread(pcib, 0x84); 371 val = pcicfgread(pcib, 0x84);
372 val |= (02 << 8); 372 val |= (02 << 8);
373 pcicfgwrite(pcib, 0x84, val); 373 pcicfgwrite(pcib, 0x84, val);
374 CFG(0xe2, 0x0f); /* use COM1/2, don't use FDC/LPT */ 374 CFG(0xe2, 0x0f); /* use COM1/2, don't use FDC/LPT */
375 val = pcicfgread(pcib, 0x84); 375 val = pcicfgread(pcib, 0x84);
376 val &= ~(02 << 8); 376 val &= ~(02 << 8);
377 pcicfgwrite(pcib, 0x84, val); 377 pcicfgwrite(pcib, 0x84, val);
378 378
379 /* route pin C to i8259 IRQ 5, pin D to 11 */ 379 /* route pin C to i8259 IRQ 5, pin D to 11 */
380 val = pcicfgread(pcib, 0x54); 380 val = pcicfgread(pcib, 0x54);
381 val = (val & 0xff) | 0xb0500000; /* Dx CB Ax xS */ 381 val = (val & 0xff) | 0xb0500000; /* Dx CB Ax xS */
382 pcicfgwrite(pcib, 0x54, val); 382 pcicfgwrite(pcib, 0x54, val);
383 383
384 /* enable EISA ELCR1 (0x4d0) and ELCR2 (0x4d1) */ 384 /* enable EISA ELCR1 (0x4d0) and ELCR2 (0x4d1) */
385 val = pcicfgread(pcib, 0x44); 385 val = pcicfgread(pcib, 0x44);
386 val = val | 0x20000000; 386 val = val | 0x20000000;
387 pcicfgwrite(pcib, 0x44, val); 387 pcicfgwrite(pcib, 0x44, val);
388 388
389 /* select level trigger for IRQ 5/11 at ELCR1/2 */ 389 /* select level trigger for IRQ 5/11 at ELCR1/2 */
390 *(volatile uint8_t *)0xfe0004d0 = 0x20; /* bit 5 */ 390 *(volatile uint8_t *)0xfe0004d0 = 0x20; /* bit 5 */
391 *(volatile uint8_t *)0xfe0004d1 = 0x08; /* bit 11 */ 391 *(volatile uint8_t *)0xfe0004d1 = 0x08; /* bit 11 */
392 392
393 /* USB and AC97 are hardwired with pin D and C */ 393 /* USB and AC97 are hardwired with pin D and C */
394 val = pcicfgread(usb12, 0x3c) &~ 0xff; 394 val = pcicfgread(usb12, 0x3c) &~ 0xff;
395 val |= 11; 395 val |= 11;
396 pcicfgwrite(usb12, 0x3c, val); 396 pcicfgwrite(usb12, 0x3c, val);
397 val = pcicfgread(usb34, 0x3c) &~ 0xff; 397 val = pcicfgread(usb34, 0x3c) &~ 0xff;
398 val |= 11; 398 val |= 11;
399 pcicfgwrite(usb34, 0x3c, val); 399 pcicfgwrite(usb34, 0x3c, val);
400 val = pcicfgread(ac97, 0x3c) &~ 0xff; 400 val = pcicfgread(ac97, 0x3c) &~ 0xff;
401 val |= 5; 401 val |= 5;
402 pcicfgwrite(ac97, 0x3c, val); 402 pcicfgwrite(ac97, 0x3c, val);
403} 403}
404 404
405void 405void
406encpcifix(struct brdprop *brd) 406encpcifix(struct brdprop *brd)
407{ 407{
408 unsigned ide, irq, net, pcib, steer, val; 408 unsigned ide, irq, net, pcib, steer, val;
409 409
410#define STEER(v, b) (((v) & (b)) ? "edge" : "level") 410#define STEER(v, b) (((v) & (b)) ? "edge" : "level")
411 pcib = pcimaketag(0, 22, 0); 411 pcib = pcimaketag(0, 22, 0);
412 ide = pcimaketag(0, 22, 1); 412 ide = pcimaketag(0, 22, 1);
413 net = pcimaketag(0, 25, 0); 413 net = pcimaketag(0, 25, 0);
414 414
415 /* 415 /*
416 * //// VIA PIRQ //// 416 * //// VIA PIRQ ////
417 * 0x57/56/55/54 - Dx CB Ax xS 417 * 0x57/56/55/54 - Dx CB Ax xS
418 */ 418 */
419 val = pcicfgread(pcib, 0x54); /* Dx CB Ax xs */ 419 val = pcicfgread(pcib, 0x54); /* Dx CB Ax xs */
420 steer = val & 0xf; 420 steer = val & 0xf;
421 irq = (val >> 12) & 0xf; /* 15:12 */ 421 irq = (val >> 12) & 0xf; /* 15:12 */
422 if (irq) { 422 if (irq) {
423 printf("pin A -> irq %d, %s\n", 423 printf("pin A -> irq %d, %s\n",
424 irq, STEER(steer, 0x1)); 424 irq, STEER(steer, 0x1));
425 } 425 }
426 irq = (val >> 16) & 0xf; /* 19:16 */ 426 irq = (val >> 16) & 0xf; /* 19:16 */
427 if (irq) { 427 if (irq) {
428 printf("pin B -> irq %d, %s\n", 428 printf("pin B -> irq %d, %s\n",
429 irq, STEER(steer, 0x2)); 429 irq, STEER(steer, 0x2));
430 } 430 }
431 irq = (val >> 20) & 0xf; /* 23:20 */ 431 irq = (val >> 20) & 0xf; /* 23:20 */
432 if (irq) { 432 if (irq) {
433 printf("pin C -> irq %d, %s\n", 433 printf("pin C -> irq %d, %s\n",
434 irq, STEER(steer, 0x4)); 434 irq, STEER(steer, 0x4));
435 } 435 }
436 irq = (val >> 28); /* 31:28 */ 436 irq = (val >> 28); /* 31:28 */
437 if (irq) { 437 if (irq) {
438 printf("pin D -> irq %d, %s\n", 438 printf("pin D -> irq %d, %s\n",
439 irq, STEER(steer, 0x8)); 439 irq, STEER(steer, 0x8));
440 } 440 }
441#if 0 441#if 0
442 /* 442 /*
443 * //// IDE fixup //// 443 * //// IDE fixup ////
444 * - "native mode" (ide 0x09) 444 * - "native mode" (ide 0x09)
445 * - use primary only (ide 0x40) 445 * - use primary only (ide 0x40)
446 */ 446 */
447 /* ide: 0x09 - programming interface; 1000'SsPp */ 447 /* ide: 0x09 - programming interface; 1000'SsPp */
448 val = pcicfgread(ide, 0x08) & 0xffff00ff; 448 val = pcicfgread(ide, 0x08) & 0xffff00ff;
449 pcicfgwrite(ide, 0x08, val | (0x8f << 8)); 449 pcicfgwrite(ide, 0x08, val | (0x8f << 8));
450 450
451 /* ide: 0x10-20 - leave them PCI memory space assigned */ 451 /* ide: 0x10-20 - leave them PCI memory space assigned */
452 452
453 /* ide: 0x40 - use primary only */ 453 /* ide: 0x40 - use primary only */
454 val = pcicfgread(ide, 0x40) &~ 03; 454 val = pcicfgread(ide, 0x40) &~ 03;
455 val |= 02; 455 val |= 02;
456 pcicfgwrite(ide, 0x40, val); 456 pcicfgwrite(ide, 0x40, val);
457#else 457#else
458 /* 458 /*
459 * //// IDE fixup //// 459 * //// IDE fixup ////
460 * - "compatiblity mode" (ide 0x09) 460 * - "compatiblity mode" (ide 0x09)
461 * - use primary only (ide 0x40) 461 * - use primary only (ide 0x40)
462 * - remove PCI pin assignment (ide 0x3d) 462 * - remove PCI pin assignment (ide 0x3d)
463 */ 463 */
464 /* ide: 0x09 - programming interface; 1000'SsPp */ 464 /* ide: 0x09 - programming interface; 1000'SsPp */
465 val = pcicfgread(ide, 0x08) & 0xffff00ff; 465 val = pcicfgread(ide, 0x08) & 0xffff00ff;
466 val |= (0x8a << 8); 466 val |= (0x8a << 8);
467 pcicfgwrite(ide, 0x08, val); 467 pcicfgwrite(ide, 0x08, val);
468 468
469 /* ide: 0x10-20 */ 469 /* ide: 0x10-20 */
470 /* 470 /*
471 experiment shows writing ide: 0x09 changes these 471 experiment shows writing ide: 0x09 changes these
472 register behaviour. The pcicfgwrite() above writes 472 register behaviour. The pcicfgwrite() above writes
473 0x8a at ide: 0x09 to make sure legacy IDE. Then 473 0x8a at ide: 0x09 to make sure legacy IDE. Then
474 reading BAR0-3 is to return value 0s even though 474 reading BAR0-3 is to return value 0s even though
475 pcisetup() has written range assignments. Value 475 pcisetup() has written range assignments. Value
476 overwrite makes no effect. Having 0x8f for native 476 overwrite makes no effect. Having 0x8f for native
477 PCIIDE doesn't change register values and brings no 477 PCIIDE doesn't change register values and brings no
478 weirdness. 478 weirdness.
479 */ 479 */
480 480
481 /* ide: 0x40 - use primary only */ 481 /* ide: 0x40 - use primary only */
482 val = pcicfgread(ide, 0x40) &~ 03; 482 val = pcicfgread(ide, 0x40) &~ 03;
483 val |= 02; 483 val |= 02;
484 pcicfgwrite(ide, 0x40, val); 484 pcicfgwrite(ide, 0x40, val);
485 485
486 /* ide: 0x3d/3c - turn off PCI pin */ 486 /* ide: 0x3d/3c - turn off PCI pin */
487 val = pcicfgread(ide, 0x3c) & 0xffff00ff; 487 val = pcicfgread(ide, 0x3c) & 0xffff00ff;
488 pcicfgwrite(ide, 0x3c, val); 488 pcicfgwrite(ide, 0x3c, val);
489#endif 489#endif
490 /* 490 /*
491 * //// USBx2, audio, and modem fixup //// 491 * //// USBx2, audio, and modem fixup ////
492 * - disable USB #0 and #1 (pcib 0x48 and 0x85) 492 * - disable USB #0 and #1 (pcib 0x48 and 0x85)
493 * - disable AC97 audio and MC97 modem (pcib 0x85) 493 * - disable AC97 audio and MC97 modem (pcib 0x85)
494 */ 494 */
495 495
496 /* pcib: 0x48 - disable USB #0 at function 2 */ 496 /* pcib: 0x48 - disable USB #0 at function 2 */
497 val = pcicfgread(pcib, 0x48); 497 val = pcicfgread(pcib, 0x48);
498 pcicfgwrite(pcib, 0x48, val | 04); 498 pcicfgwrite(pcib, 0x48, val | 04);
499 499
500 /* pcib: 0x85 - disable USB #1 at function 3 */ 500 /* pcib: 0x85 - disable USB #1 at function 3 */
501 /* pcib: 0x85 - disable AC97/MC97 at function 5/6 */ 501 /* pcib: 0x85 - disable AC97/MC97 at function 5/6 */
502 val = pcicfgread(pcib, 0x84); 502 val = pcicfgread(pcib, 0x84);
503 pcicfgwrite(pcib, 0x84, val | 0x1c00); 503 pcicfgwrite(pcib, 0x84, val | 0x1c00);
504 504
505 /* 505 /*
506 * //// fxp fixup //// 506 * //// fxp fixup ////
507 * - use PCI pin A line 25 (fxp 0x3d/3c) 507 * - use PCI pin A line 25 (fxp 0x3d/3c)
508 */ 508 */
509 /* 0x3d/3c - PCI pin/line */ 509 /* 0x3d/3c - PCI pin/line */
510 val = pcicfgread(net, 0x3c) & 0xffff0000; 510 val = pcicfgread(net, 0x3c) & 0xffff0000;
511 val |= (('A' - '@') << 8) | 25; 511 val |= (('A' - '@') << 8) | 25;
512 pcicfgwrite(net, 0x3c, val); 512 pcicfgwrite(net, 0x3c, val);
513} 513}
514 514
515void 515void
516motsetup(struct brdprop *brd) 516motsetup(struct brdprop *brd)
517{ 517{
518 518
519#ifdef COSNAME 519#ifdef COSNAME
520 brd->consname = CONSNAME; 520 brd->consname = CONSNAME;
521#endif 521#endif
522#ifdef CONSPORT 522#ifdef CONSPORT
523 brd->consport = CONSPORT; 523 brd->consport = CONSPORT;
524#endif 524#endif
525#ifdef CONSSPEED 525#ifdef CONSSPEED
526 brd->consspeed = CONSSPEED; 526 brd->consspeed = CONSSPEED;
527#endif 527#endif
528} 528}
529 529
530void 530void
531motbrdfix(struct brdprop *brd) 531motbrdfix(struct brdprop *brd)
532{ 532{
533 533
534/* 534/*
535 * WinBond/Symphony Lab 83C553 with PC87308 "SuperIO" 535 * WinBond/Symphony Lab 83C553 with PC87308 "SuperIO"
536 * 536 *
537 * 0.11.0 10ad.0565 PCI-ISA bridge 537 * 0.11.0 10ad.0565 PCI-ISA bridge
538 * 0.11.1 10ad.0105 IDE (slide) 538 * 0.11.1 10ad.0105 IDE (slide)
539 */ 539 */
540} 540}
541 541
542void 542void
543motpcifix(struct brdprop *brd) 543motpcifix(struct brdprop *brd)
544{ 544{
545 unsigned ide, net, pcib, steer, val; 545 unsigned ide, net, pcib, steer, val;
546 int line; 546 int line;
547 547
548 pcib = pcimaketag(0, 11, 0); 548 pcib = pcimaketag(0, 11, 0);
549 ide = pcimaketag(0, 11, 1); 549 ide = pcimaketag(0, 11, 1);
550 net = pcimaketag(0, 15, 0); 550 net = pcimaketag(0, 15, 0);
551 551
552 /* 552 /*
553 * //// WinBond PIRQ //// 553 * //// WinBond PIRQ ////
554 * 0x40 - bit 5 (0x20) indicates PIRQ presense 554 * 0x40 - bit 5 (0x20) indicates PIRQ presense
555 * 0x60 - PIRQ interrupt routing steer 555 * 0x60 - PIRQ interrupt routing steer
556 */ 556 */
557 if (pcicfgread(pcib, 0x40) & 0x20) { 557 if (pcicfgread(pcib, 0x40) & 0x20) {
558 steer = pcicfgread(pcib, 0x60); 558 steer = pcicfgread(pcib, 0x60);
559 if ((steer & 0x80808080) == 0x80808080) 559 if ((steer & 0x80808080) == 0x80808080)
560 printf("PIRQ[0-3] disabled\n"); 560 printf("PIRQ[0-3] disabled\n");
561 else { 561 else {
562 unsigned i, v = steer; 562 unsigned i, v = steer;
563 for (i = 0; i < 4; i++, v >>= 8) { 563 for (i = 0; i < 4; i++, v >>= 8) {
564 if ((v & 0x80) != 0 || (v & 0xf) == 0) 564 if ((v & 0x80) != 0 || (v & 0xf) == 0)
565 continue; 565 continue;
566 printf("PIRQ[%d]=%d\n", i, v & 0xf); 566 printf("PIRQ[%d]=%d\n", i, v & 0xf);
567 } 567 }
568 } 568 }
569 } 569 }
570#if 1 570#if 1
571 /* 571 /*
572 * //// IDE fixup -- case A //// 572 * //// IDE fixup -- case A ////
573 * - "native PCI mode" (ide 0x09) 573 * - "native PCI mode" (ide 0x09)
574 * - don't use ISA IRQ14/15 (pcib 0x43) 574 * - don't use ISA IRQ14/15 (pcib 0x43)
575 * - native IDE for both channels (ide 0x40) 575 * - native IDE for both channels (ide 0x40)
576 * - LEGIRQ bit 11 steers interrupt to pin C (ide 0x40) 576 * - LEGIRQ bit 11 steers interrupt to pin C (ide 0x40)
577 * - sign as PCI pin C line 11 (ide 0x3d/3c) 577 * - sign as PCI pin C line 11 (ide 0x3d/3c)
578 */ 578 */
579 /* ide: 0x09 - programming interface; 1000'SsPp */ 579 /* ide: 0x09 - programming interface; 1000'SsPp */
580 val = pcicfgread(ide, 0x08); 580 val = pcicfgread(ide, 0x08);
581 val &= 0xffff00ff; 581 val &= 0xffff00ff;
582 pcicfgwrite(ide, 0x08, val | (0x8f << 8)); 582 pcicfgwrite(ide, 0x08, val | (0x8f << 8));
583 583
584 /* pcib: 0x43 - IDE interrupt routing */ 584 /* pcib: 0x43 - IDE interrupt routing */
585 val = pcicfgread(pcib, 0x40) & 0x00ffffff; 585 val = pcicfgread(pcib, 0x40) & 0x00ffffff;
586 pcicfgwrite(pcib, 0x40, val); 586 pcicfgwrite(pcib, 0x40, val);
587 587
588 /* pcib: 0x45/44 - PCI interrupt routing */ 588 /* pcib: 0x45/44 - PCI interrupt routing */
589 val = pcicfgread(pcib, 0x44) & 0xffff0000; 589 val = pcicfgread(pcib, 0x44) & 0xffff0000;
590 pcicfgwrite(pcib, 0x44, val); 590 pcicfgwrite(pcib, 0x44, val);
591 591
592 /* ide: 0x41/40 - IDE channel */ 592 /* ide: 0x41/40 - IDE channel */
593 val = pcicfgread(ide, 0x40) & 0xffff0000; 593 val = pcicfgread(ide, 0x40) & 0xffff0000;
594 val |= (1 << 11) | 0x33; /* LEGIRQ turns on PCI interrupt */ 594 val |= (1 << 11) | 0x33; /* LEGIRQ turns on PCI interrupt */
595 pcicfgwrite(ide, 0x40, val); 595 pcicfgwrite(ide, 0x40, val);
596 596
597 /* ide: 0x3d/3c - use PCI pin C/line 11 */ 597 /* ide: 0x3d/3c - use PCI pin C/line 11 */
598 val = pcicfgread(ide, 0x3c) & 0xffffff00; 598 val = pcicfgread(ide, 0x3c) & 0xffffff00;
599 val |= 11; /* pin designation is hardwired to pin A */ 599 val |= 11; /* pin designation is hardwired to pin A */
600 pcicfgwrite(ide, 0x3c, val); 600 pcicfgwrite(ide, 0x3c, val);
601#else 601#else
602 /* 602 /*
603 * //// IDE fixup -- case B //// 603 * //// IDE fixup -- case B ////
604 * - "compatiblity mode" (ide 0x09) 604 * - "compatiblity mode" (ide 0x09)
605 * - IDE primary/secondary interrupt routing (pcib 0x43) 605 * - IDE primary/secondary interrupt routing (pcib 0x43)
606 * - PCI interrupt routing (pcib 0x45/44) 606 * - PCI interrupt routing (pcib 0x45/44)
607 * - no PCI pin/line assignment (ide 0x3d/3c) 607 * - no PCI pin/line assignment (ide 0x3d/3c)
608 */ 608 */
609 /* ide: 0x09 - programming interface; 1000'SsPp */ 609 /* ide: 0x09 - programming interface; 1000'SsPp */
610 val = pcicfgread(ide, 0x08); 610 val = pcicfgread(ide, 0x08);
611 val &= 0xffff00ff; 611 val &= 0xffff00ff;
612 pcicfgwrite(ide, 0x08, val | (0x8a << 8)); 612 pcicfgwrite(ide, 0x08, val | (0x8a << 8));
613 613
614 /* pcib: 0x43 - IDE interrupt routing */ 614 /* pcib: 0x43 - IDE interrupt routing */
615 val = pcicfgread(pcib, 0x40) & 0x00ffffff; 615 val = pcicfgread(pcib, 0x40) & 0x00ffffff;
616 pcicfgwrite(pcib, 0x40, val | (0xee << 24)); 616 pcicfgwrite(pcib, 0x40, val | (0xee << 24));
617 617
618 /* ide: 0x45/44 - PCI interrupt routing */ 618 /* ide: 0x45/44 - PCI interrupt routing */
619 val = pcicfgread(ide, 0x44) & 0xffff0000; 619 val = pcicfgread(ide, 0x44) & 0xffff0000;
620 pcicfgwrite(ide, 0x44, val); 620 pcicfgwrite(ide, 0x44, val);
621 621
622 /* ide: 0x3d/3c - turn off PCI pin/line */ 622 /* ide: 0x3d/3c - turn off PCI pin/line */
623 val = pcicfgread(ide, 0x3c) & 0xffff0000; 623 val = pcicfgread(ide, 0x3c) & 0xffff0000;
624 pcicfgwrite(ide, 0x3c, val); 624 pcicfgwrite(ide, 0x3c, val);
625#endif 625#endif
626 626
627 /* 627 /*
628 * //// fxp fixup //// 628 * //// fxp fixup ////
629 * - use PCI pin A line 15 (fxp 0x3d/3c) 629 * - use PCI pin A line 15 (fxp 0x3d/3c)
630 */ 630 */
631 val = pcicfgread(net, 0x3c) & 0xffff0000; 631 val = pcicfgread(net, 0x3c) & 0xffff0000;
632 pcidecomposetag(net, NULL, &line, NULL); 632 pcidecomposetag(net, NULL, &line, NULL);
633 val |= (('A' - '@') << 8) | line; 633 val |= (('A' - '@') << 8) | line;
634 pcicfgwrite(net, 0x3c, val); 634 pcicfgwrite(net, 0x3c, val);
635} 635}
636 636
637void 637void
638kurosetup(struct brdprop *brd) 638kurosetup(struct brdprop *brd)
639{ 639{
640 640
641 if (PCI_VENDOR(pcicfgread(pcimaketag(0, 11, 0), PCI_ID_REG)) == 0x10ec) 641 if (PCI_VENDOR(pcicfgread(pcimaketag(0, 11, 0), PCI_ID_REG)) == 0x10ec)
642 brd->extclk = 32768000; /* decr 2457600Hz */ 642 brd->extclk = 32768000; /* decr 2457600Hz */
643 else 643 else
644 brd->extclk = 32521333; /* decr 2439100Hz */ 644 brd->extclk = 32521333; /* decr 2439100Hz */
645} 645}
646 646
647void 647void
648kurobrdfix(struct brdprop *brd) 648kurobrdfix(struct brdprop *brd)
649{ 649{
650 650
651 init_uart(uart2base, 9600, LCR_8BITS | LCR_PEVEN); 651 init_uart(uart2base, 9600, LCR_8BITS | LCR_PEVEN);
652 /* Stop Watchdog */ 652 /* Stop Watchdog */
653 send_sat("AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK"); 653 send_sat("AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK");
654} 654}
655 655
656void 656void
657synobrdfix(struct brdprop *brd) 657synobrdfix(struct brdprop *brd)
658{ 658{
659 659
660 init_uart(uart2base, 9600, LCR_8BITS | LCR_PNONE); 660 init_uart(uart2base, 9600, LCR_8BITS | LCR_PNONE);
661 /* beep, power LED on, status LED off */ 661 /* beep, power LED on, status LED off */
662 send_sat("247"); 662 send_sat("247");
663} 663}
664 664
665void 665void
666synoreset() 666synoreset()
667{ 667{
668 668
669 send_sat("C"); 669 send_sat("C");
670 /*NOTREACHED*/ 670 /*NOTREACHED*/
671} 671}
672 672
673void 673void
674qnapbrdfix(struct brdprop *brd) 674qnapbrdfix(struct brdprop *brd)
675{ 675{
676 676
677 init_uart(uart2base, 19200, LCR_8BITS | LCR_PNONE); 677 init_uart(uart2base, 19200, LCR_8BITS | LCR_PNONE);
678 /* beep, status LED red */ 678 /* beep, status LED red */
679 send_sat("PW"); 679 send_sat("PW");
680} 680}
681 681
682void 682void
683qnapreset() 683qnapreset()
684{ 684{
685 685
686 send_sat("f"); 686 send_sat("f");
687 /*NOTREACHED*/ 687 /*NOTREACHED*/
688} 688}
689 689
690void 690void
691iomegabrdfix(struct brdprop *brd) 691iomegabrdfix(struct brdprop *brd)
692{ 692{
693 693
694 init_uart(uart2base, 9600, LCR_8BITS | LCR_PNONE); 694 init_uart(uart2base, 9600, LCR_8BITS | LCR_PNONE);
695 /* illuminate LEDs */ 695 /* illuminate LEDs */
696} 696}
697 697
698void 698void
699dlinkbrdfix(struct brdprop *brd) 699dlinkbrdfix(struct brdprop *brd)
700{ 700{
701 701
702 init_uart(uart2base, 9600, LCR_8BITS | LCR_PNONE); 702 init_uart(uart2base, 9600, LCR_8BITS | LCR_PNONE);
703 send_sat("SYN\n"); 703 send_sat("SYN\n");
704 send_sat("ZWO\n"); /* power LED solid on */ 704 send_sat("ZWO\n"); /* power LED solid on */
705} 705}
706 706
707void 707void
708nhnasbrdfix(struct brdprop *brd) 708nhnasbrdfix(struct brdprop *brd)
709{ 709{
710 710
711 /* illuminate LEDs */ 711 /* illuminate LEDs */
712} 712}
713 713
714void 714void
715_rtt(void) 715_rtt(void)
716{ 716{
717 uint32_t msr; 717 uint32_t msr;
718 718
719 netif_shutdown_all(); 719 netif_shutdown_all();
720 720
721 if (brdprop->reset != NULL) 721 if (brdprop->reset != NULL)
722 (*brdprop->reset)(); 722 (*brdprop->reset)();
723 else { 723 else {
724 msr = mfmsr(); 724 msr = mfmsr();
725 msr &= ~PSL_EE; 725 msr &= ~PSL_EE;
726 mtmsr(msr); 726 mtmsr(msr);
727 asm volatile ("sync; isync"); 727 asm volatile ("sync; isync");
728 asm volatile("mtspr %0,%1" : : "K"(81), "r"(0)); 728 asm volatile("mtspr %0,%1" : : "K"(81), "r"(0));
729 msr &= ~(PSL_ME | PSL_DR | PSL_IR); 729 msr &= ~(PSL_ME | PSL_DR | PSL_IR);
730 mtmsr(msr); 730 mtmsr(msr);
731 asm volatile ("sync; isync"); 731 asm volatile ("sync; isync");
732 run(0, 0, 0, 0, (void *)0xFFF00100); /* reset entry */ 732 run(0, 0, 0, 0, (void *)0xFFF00100); /* reset entry */
733 } 733 }
734 /*NOTREACHED*/ 734 /*NOTREACHED*/
735} 735}
736 736
737satime_t 737satime_t
738getsecs(void) 738getsecs(void)
739{ 739{
740 u_quad_t tb = mftb(); 740 u_quad_t tb = mftb();
741 741
742 return (tb / ticks_per_sec); 742 return (tb / ticks_per_sec);
743} 743}
744 744
745/* 745/*
746 * Wait for about n microseconds (at least!). 746 * Wait for about n microseconds (at least!).
747 */ 747 */
748void 748void
749delay(u_int n) 749delay(u_int n)
750{ 750{
751 u_quad_t tb; 751 u_quad_t tb;
752 u_long scratch, tbh, tbl; 752 u_long scratch, tbh, tbl;
753 753
754 tb = mftb(); 754 tb = mftb();
755 tb += (n * 1000 + ns_per_tick - 1) / ns_per_tick; 755 tb += (n * 1000 + ns_per_tick - 1) / ns_per_tick;
756 tbh = tb >> 32; 756 tbh = tb >> 32;
757 tbl = tb; 757 tbl = tb;
758 asm volatile ("1: mftbu %0; cmpw %0,%1; blt 1b; bgt 2f; mftb %0; cmpw 0, %0,%2; blt 1b; 2:" : "=&r"(scratch) : "r"(tbh), "r"(tbl)); 758 asm volatile ("1: mftbu %0; cmpw %0,%1; blt 1b; bgt 2f; mftb %0; cmpw 0, %0,%2; blt 1b; 2:" : "=&r"(scratch) : "r"(tbh), "r"(tbl));
759} 759}
760 760
761void 761void
762_wb(uint32_t adr, uint32_t siz) 762_wb(uint32_t adr, uint32_t siz)
763{ 763{
764 uint32_t bnd; 764 uint32_t bnd;
765 765
766 asm volatile("eieio"); 766 asm volatile("eieio");
767 for (bnd = adr + siz; adr < bnd; adr += dcache_line_size) 767 for (bnd = adr + siz; adr < bnd; adr += dcache_line_size)
768 asm volatile ("dcbst 0,%0" :: "r"(adr)); 768 asm volatile ("dcbst 0,%0" :: "r"(adr));
769 asm volatile ("sync"); 769 asm volatile ("sync");
770} 770}
771 771
772void 772void
773_wbinv(uint32_t adr, uint32_t siz) 773_wbinv(uint32_t adr, uint32_t siz)
774{ 774{
775 uint32_t bnd; 775 uint32_t bnd;
776 776
777 asm volatile("eieio"); 777 asm volatile("eieio");
778 for (bnd = adr + siz; adr < bnd; adr += dcache_line_size) 778 for (bnd = adr + siz; adr < bnd; adr += dcache_line_size)
779 asm volatile ("dcbf 0,%0" :: "r"(adr)); 779 asm volatile ("dcbf 0,%0" :: "r"(adr));
780 asm volatile ("sync"); 780 asm volatile ("sync");
781} 781}
782 782
783void 783void
784_inv(uint32_t adr, uint32_t siz) 784_inv(uint32_t adr, uint32_t siz)
785{ 785{
786 uint32_t bnd, off; 786 uint32_t bnd, off;
787 787
788 off = adr & (dcache_line_size - 1); 788 off = adr & (dcache_line_size - 1);
789 adr -= off; 789 adr -= off;
790 siz += off; 790 siz += off;
791 asm volatile ("eieio"); 791 asm volatile ("eieio");
792 if (off != 0) { 792 if (off != 0) {
793 /* wbinv() leading unaligned dcache line */ 793 /* wbinv() leading unaligned dcache line */
794 asm volatile ("dcbf 0,%0" :: "r"(adr)); 794 asm volatile ("dcbf 0,%0" :: "r"(adr));
795 if (siz < dcache_line_size) 795 if (siz < dcache_line_size)
796 goto done; 796 goto done;
797 adr += dcache_line_size; 797 adr += dcache_line_size;
798 siz -= dcache_line_size; 798 siz -= dcache_line_size;
799 } 799 }
800 bnd = adr + siz; 800 bnd = adr + siz;
801 off = bnd & (dcache_line_size - 1); 801 off = bnd & (dcache_line_size - 1);
802 if (off != 0) { 802 if (off != 0) {
803 /* wbinv() trailing unaligned dcache line */ 803 /* wbinv() trailing unaligned dcache line */
804 asm volatile ("dcbf 0,%0" :: "r"(bnd)); /* it's OK */ 804 asm volatile ("dcbf 0,%0" :: "r"(bnd)); /* it's OK */
805 if (siz < dcache_line_size) 805 if (siz < dcache_line_size)
806 goto done; 806 goto done;
807 siz -= off; 807 siz -= off;
808 } 808 }
809 for (bnd = adr + siz; adr < bnd; adr += dcache_line_size) { 809 for (bnd = adr + siz; adr < bnd; adr += dcache_line_size) {
810 /* inv() intermediate dcache lines if ever */ 810 /* inv() intermediate dcache lines if ever */
811 asm volatile ("dcbi 0,%0" :: "r"(adr)); 811 asm volatile ("dcbi 0,%0" :: "r"(adr));
812 } 812 }
813 done: 813 done:
814 asm volatile ("sync"); 814 asm volatile ("sync");
815} 815}
816 816
817static inline uint32_t 817static inline uint32_t
818mfmsr(void) 818mfmsr(void)
819{ 819{
820 uint32_t msr; 820 uint32_t msr;
821 821
822 asm volatile ("mfmsr %0" : "=r"(msr)); 822 asm volatile ("mfmsr %0" : "=r"(msr));
823 return msr; 823 return msr;
824} 824}
825 825
826static inline void 826static inline void
827mtmsr(uint32_t msr) 827mtmsr(uint32_t msr)
828{ 828{
829 asm volatile ("mtmsr %0" : : "r"(msr)); 829 asm volatile ("mtmsr %0" : : "r"(msr));
830} 830}
831 831
832static inline uint32_t 832static inline uint32_t
833cputype(void) 833cputype(void)
834{ 834{
835 uint32_t pvr; 835 uint32_t pvr;
836 836
837 asm volatile ("mfpvr %0" : "=r"(pvr)); 837 asm volatile ("mfpvr %0" : "=r"(pvr));
838 return pvr >> 16; 838 return pvr >> 16;
839} 839}
840 840
841static inline u_quad_t 841static inline u_quad_t
842mftb(void) 842mftb(void)
843{ 843{
844 u_long scratch; 844 u_long scratch;
845 u_quad_t tb; 845 u_quad_t tb;
846 846
847 asm ("1: mftbu %0; mftb %0+1; mftbu %1; cmpw %0,%1; bne 1b" 847 asm ("1: mftbu %0; mftb %0+1; mftbu %1; cmpw %0,%1; bne 1b"
848 : "=r"(tb), "=r"(scratch)); 848 : "=r"(tb), "=r"(scratch));
849 return tb; 849 return tb;
850} 850}
851 851
852static void 852static void
853init_uart(unsigned base, unsigned speed, uint8_t lcr) 853init_uart(unsigned base, unsigned speed, uint8_t lcr)
854{ 854{
855 unsigned div; 855 unsigned div;
856 856
857 div = busclock / speed / 16; 857 div = busclock / speed / 16;
858 UART_WRITE(base, LCR, 0x80); /* turn on DLAB bit */ 858 UART_WRITE(base, LCR, 0x80); /* turn on DLAB bit */
859 UART_WRITE(base, FCR, 0x00); 859 UART_WRITE(base, FCR, 0x00);
860 UART_WRITE(base, DMB, div >> 8); /* set speed */ 860 UART_WRITE(base, DMB, div >> 8); /* set speed */
861 UART_WRITE(base, DLB, div & 0xff); 861 UART_WRITE(base, DLB, div & 0xff);
862 UART_WRITE(base, LCR, lcr); 862 UART_WRITE(base, LCR, lcr);
863 UART_WRITE(base, FCR, 0x07); /* FIFO on, TXRX FIFO reset */ 863 UART_WRITE(base, FCR, 0x07); /* FIFO on, TXRX FIFO reset */
864 UART_WRITE(base, IER, 0x00); /* make sure INT disabled */ 864 UART_WRITE(base, IER, 0x00); /* make sure INT disabled */
865} 865}
866 866
867/* talk to satellite processor */ 867/* talk to satellite processor */
868static void 868static void
869send_sat(char *msg) 869send_sat(char *msg)
870{ 870{
871 unsigned savedbase; 871 unsigned savedbase;
872 872
873 savedbase = uart1base; 873 savedbase = uart1base;
874 uart1base = uart2base; 874 uart1base = uart2base;
875 while (*msg) 875 while (*msg)
876 putchar(*msg++); 876 putchar(*msg++);
877 uart1base = savedbase; 877 uart1base = savedbase;
878} 878}
879 879
880void 880void
881putchar(int c) 881putchar(int c)
882{ 882{
883 unsigned timo, lsr; 883 unsigned timo, lsr;
884 884
885 if (c == '\n') 885 if (c == '\n')
886 putchar('\r'); 886 putchar('\r');
887 887
888 timo = 0x00100000; 888 timo = 0x00100000;
889 do { 889 do {
890 lsr = UART_READ(uart1base, LSR); 890 lsr = UART_READ(uart1base, LSR);
891 } while (timo-- > 0 && (lsr & LSR_THRE) == 0); 891 } while (timo-- > 0 && (lsr & LSR_THRE) == 0);
892 if (timo > 0) 892 if (timo > 0)
893 UART_WRITE(uart1base, THR, c); 893 UART_WRITE(uart1base, THR, c);
894} 894}
895 895
896int 896int
897getchar(void) 897getchar(void)
898{ 898{
899 unsigned lsr; 899 unsigned lsr;
900 900
901 do { 901 do {
902 lsr = UART_READ(uart1base, LSR); 902 lsr = UART_READ(uart1base, LSR);
903 } while ((lsr & LSR_DRDY) == 0); 903 } while ((lsr & LSR_DRDY) == 0);
904 return UART_READ(uart1base, RBR); 904 return UART_READ(uart1base, RBR);
905} 905}
906 906
907int 907int
908tstchar(void) 908tstchar(void)
909{ 909{
910 return (UART_READ(uart1base, LSR) & LSR_DRDY) != 0; 910 return (UART_READ(uart1base, LSR) & LSR_DRDY) != 0;
911} 911}
912 912
913unsigned 913unsigned
914mpc107memsize() 914mpc107memsize()
915{ 915{
916 unsigned bankn, end, n, tag, val; 916 unsigned bankn, end, n, tag, val;
917 917
918 tag = pcimaketag(0, 0, 0); 918 tag = pcimaketag(0, 0, 0);
919 919
920 if (brdtype == BRD_ENCOREPP1) { 920 if (brdtype == BRD_ENCOREPP1) {
921 /* the brd's PPCBOOT looks to have erroneous values */ 921 /* the brd's PPCBOOT looks to have erroneous values */
922 unsigned tbl[] = { 922 unsigned tbl[] = {
923#define MPC106_MEMSTARTADDR1 0x80 923#define MPC106_MEMSTARTADDR1 0x80
924#define MPC106_EXTMEMSTARTADDR1 0x88 924#define MPC106_EXTMEMSTARTADDR1 0x88
925#define MPC106_MEMENDADDR1 0x90 925#define MPC106_MEMENDADDR1 0x90
926#define MPC106_EXTMEMENDADDR1 0x98 926#define MPC106_EXTMEMENDADDR1 0x98
927#define MPC106_MEMEN 0xa0 927#define MPC106_MEMEN 0xa0
928#define BK0_S 0x00000000 928#define BK0_S 0x00000000
929#define BK0_E (128 << 20) - 1 929#define BK0_E (128 << 20) - 1
930#define BK1_S 0x3ff00000 930#define BK1_S 0x3ff00000
931#define BK1_E 0x3fffffff 931#define BK1_E 0x3fffffff
932#define BK2_S 0x3ff00000 932#define BK2_S 0x3ff00000
933#define BK2_E 0x3fffffff 933#define BK2_E 0x3fffffff
934#define BK3_S 0x3ff00000 934#define BK3_S 0x3ff00000
935#define BK3_E 0x3fffffff 935#define BK3_E 0x3fffffff
936#define AR(v, s) ((((v) & SAR_MASK) >> SAR_SHIFT) << (s)) 936#define AR(v, s) ((((v) & SAR_MASK) >> SAR_SHIFT) << (s))
937#define XR(v, s) ((((v) & EAR_MASK) >> EAR_SHIFT) << (s)) 937#define XR(v, s) ((((v) & EAR_MASK) >> EAR_SHIFT) << (s))
938#define SAR_MASK 0x0ff00000 938#define SAR_MASK 0x0ff00000
939#define SAR_SHIFT 20 939#define SAR_SHIFT 20
940#define EAR_MASK 0x30000000 940#define EAR_MASK 0x30000000
941#define EAR_SHIFT 28 941#define EAR_SHIFT 28
942 AR(BK0_S, 0) | AR(BK1_S, 8) | AR(BK2_S, 16) | AR(BK3_S, 24), 942 AR(BK0_S, 0) | AR(BK1_S, 8) | AR(BK2_S, 16) | AR(BK3_S, 24),
943 XR(BK0_S, 0) | XR(BK1_S, 8) | XR(BK2_S, 16) | XR(BK3_S, 24), 943 XR(BK0_S, 0) | XR(BK1_S, 8) | XR(BK2_S, 16) | XR(BK3_S, 24),
944 AR(BK0_E, 0) | AR(BK1_E, 8) | AR(BK2_E, 16) | AR(BK3_E, 24), 944 AR(BK0_E, 0) | AR(BK1_E, 8) | AR(BK2_E, 16) | AR(BK3_E, 24),
945 XR(BK0_E, 0) | XR(BK1_E, 8) | XR(BK2_E, 16) | XR(BK3_E, 24), 945 XR(BK0_E, 0) | XR(BK1_E, 8) | XR(BK2_E, 16) | XR(BK3_E, 24),
946 }; 946 };
947 tag = pcimaketag(0, 0, 0); 947 tag = pcimaketag(0, 0, 0);
948 pcicfgwrite(tag, MPC106_MEMSTARTADDR1, tbl[0]); 948 pcicfgwrite(tag, MPC106_MEMSTARTADDR1, tbl[0]);
949 pcicfgwrite(tag, MPC106_EXTMEMSTARTADDR1, tbl[1]); 949 pcicfgwrite(tag, MPC106_EXTMEMSTARTADDR1, tbl[1]);
950 pcicfgwrite(tag, MPC106_MEMENDADDR1, tbl[2]); 950 pcicfgwrite(tag, MPC106_MEMENDADDR1, tbl[2]);
951 pcicfgwrite(tag, MPC106_EXTMEMENDADDR1, tbl[3]); 951 pcicfgwrite(tag, MPC106_EXTMEMENDADDR1, tbl[3]);
952 pcicfgwrite(tag, MPC106_MEMEN, 1); 952 pcicfgwrite(tag, MPC106_MEMEN, 1);
953 } 953 }
954 954
955 bankn = 0; 955 bankn = 0;
956 val = pcicfgread(tag, MPC106_MEMEN); 956 val = pcicfgread(tag, MPC106_MEMEN);
957 for (n = 0; n < 4; n++) { 957 for (n = 0; n < 4; n++) {
958 if ((val & (1U << n)) == 0) 958 if ((val & (1U << n)) == 0)
959 break; 959 break;
960 bankn = n; 960 bankn = n;
961 } 961 }
962 bankn = bankn * 8; 962 bankn = bankn * 8;
963 963
964 val = pcicfgread(tag, MPC106_EXTMEMENDADDR1); 964 val = pcicfgread(tag, MPC106_EXTMEMENDADDR1);
965 end = ((val >> bankn) & 0x03) << 28; 965 end = ((val >> bankn) & 0x03) << 28;
966 val = pcicfgread(tag, MPC106_MEMENDADDR1); 966 val = pcicfgread(tag, MPC106_MEMENDADDR1);
967 end |= ((val >> bankn) & 0xff) << 20; 967 end |= ((val >> bankn) & 0xff) << 20;
968 end |= 0xfffff; 968 end |= 0xfffff;
969 969
970 return (end + 1); /* assume the end address matches total amount */ 970 return (end + 1); /* assume the end address matches total amount */
971} 971}
972 972
973struct fis_dir_entry { 973struct fis_dir_entry {
974 char name[16]; 974 char name[16];
975 uint32_t startaddr; 975 uint32_t startaddr;
976 uint32_t loadaddr; 976 uint32_t loadaddr;
977 uint32_t flashsize; 977 uint32_t flashsize;
978 uint32_t entryaddr; 978 uint32_t entryaddr;
979 uint32_t filesize; 979 uint32_t filesize;
980 char pad[256 - (16 + 5 * sizeof(uint32_t))]; 980 char pad[256 - (16 + 5 * sizeof(uint32_t))];
981}; 981};
982 982
983#define FIS_LOWER_LIMIT 0xfff00000 983#define FIS_LOWER_LIMIT 0xfff00000
984 984
985/* 985/*
986 * Look for a Redboot-style Flash Image System FIS-directory and 986 * Look for a Redboot-style Flash Image System FIS-directory and
987 * return a pointer to the start address of the requested file. 987 * return a pointer to the start address of the requested file.
988 */ 988 */
989static void * 989static void *
990redboot_fis_lookup(const char *filename) 990redboot_fis_lookup(const char *filename)
991{ 991{
992 static const char FISdirname[16] = { 992 static const char FISdirname[16] = {
993 'F', 'I', 'S', ' ', 993 'F', 'I', 'S', ' ',
994 'd', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 0, 0, 0 994 'd', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 0, 0, 0
995 }; 995 };
996 struct fis_dir_entry *dir; 996 struct fis_dir_entry *dir;
997 997
998 /* 998 /*
999 * The FIS directory is usually in the last sector of the flash. 999 * The FIS directory is usually in the last sector of the flash.
1000 * But we do not know the sector size (erase size), so start 1000 * But we do not know the sector size (erase size), so start
1001 * at 0xffffff00 and scan backwards in steps of the FIS directory 1001 * at 0xffffff00 and scan backwards in steps of the FIS directory
1002 * entry size (0x100). 1002 * entry size (0x100).
1003 */ 1003 */
1004 for (dir = (struct fis_dir_entry *)0xffffff00; 1004 for (dir = (struct fis_dir_entry *)0xffffff00;
1005 (uint32_t)dir >= FIS_LOWER_LIMIT; dir--) 1005 (uint32_t)dir >= FIS_LOWER_LIMIT; dir--)
1006 if (memcmp(dir->name, FISdirname, sizeof(FISdirname)) == 0) 1006 if (memcmp(dir->name, FISdirname, sizeof(FISdirname)) == 0)
1007 break; 1007 break;
1008 if ((uint32_t)dir < FIS_LOWER_LIMIT) { 1008 if ((uint32_t)dir < FIS_LOWER_LIMIT) {
1009 printf("No FIS directory found!\n"); 1009 printf("No FIS directory found!\n");
1010 return NULL; 1010 return NULL;
1011 } 1011 }
1012 1012
1013 /* Now find filename by scanning the directory from beginning. */ 1013 /* Now find filename by scanning the directory from beginning. */
1014 dir = (struct fis_dir_entry *)dir->startaddr; 1014 dir = (struct fis_dir_entry *)dir->startaddr;
1015 while (dir->name[0] != 0xff && (uint32_t)dir < 0xffffff00) { 1015 while (dir->name[0] != 0xff && (uint32_t)dir < 0xffffff00) {
1016 if (strcmp(dir->name, filename) == 0) 1016 if (strcmp(dir->name, filename) == 0)
1017 return (void *)dir->startaddr; /* found */ 1017 return (void *)dir->startaddr; /* found */
1018 dir++; 1018 dir++;
1019 } 1019 }
1020 printf("\"%s\" not found in FIS directory!\n", filename); 1020 printf("\"%s\" not found in FIS directory!\n", filename);
1021 return NULL; 1021 return NULL;
1022} 1022}
1023 1023
1024static void 1024static void
1025read_mac_string(uint8_t *mac, char *p) 1025read_mac_string(uint8_t *mac, char *p)
1026{ 1026{
1027 int i; 1027 int i;
1028 1028
1029 for (i = 0; i < 6; i++, p += 3) 1029 for (i = 0; i < 6; i++, p += 3)
1030 *mac++ = read_hex(p); 1030 *mac++ = read_hex(p);
1031} 1031}
1032 1032
1033/* 1033/*
1034 * For cost saving reasons some NAS boxes lack SEEPROM for NIC's 1034 * For cost saving reasons some NAS boxes lack SEEPROM for NIC's
1035 * ethernet address and keep it in their Flash memory instead. 1035 * ethernet address and keep it in their Flash memory instead.
1036 */ 1036 */
1037void 1037void
1038read_mac_from_flash(uint8_t *mac) 1038read_mac_from_flash(uint8_t *mac)
1039{ 1039{
1040 uint8_t *p; 1040 uint8_t *p;
1041 1041
1042 switch (brdtype) { 1042 switch (brdtype) {
1043 case BRD_SYNOLOGY: 1043 case BRD_SYNOLOGY:
1044 p = redboot_fis_lookup("vendor"); 1044 p = redboot_fis_lookup("vendor");
1045 if (p == NULL) 1045 if (p == NULL)
1046 break; 1046 break;
1047 memcpy(mac, p, 6); 1047 memcpy(mac, p, 6);
1048 return; 1048 return;
1049 case BRD_DLINKDSM: 1049 case BRD_DLINKDSM:
1050 read_mac_string(mac, (char *)0xfff0ff80); 1050 read_mac_string(mac, (char *)0xfff0ff80);
1051 return; 1051 return;
1052 default: 1052 default:
1053 printf("Warning: This board has no known method defined " 1053 printf("Warning: This board has no known method defined "
1054 "to determine its MAC address!\n"); 1054 "to determine its MAC address!\n");
1055 break; 1055 break;
1056 } 1056 }
1057 1057
1058 /* set to 00:00:00:00:00:00 in case of error */ 1058 /* set to 00:00:00:00:00:00 in case of error */
1059 memset(mac, 0, 6); 1059 memset(mac, 0, 6);
1060} 1060}