1 /* $NetBSD: brdsetup.c,v 1.41 2022/02/16 23:49:27 riastradh Exp $ */
2 
3 /*-
4  * Copyright (c) 2008 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Tohru Nishimura.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
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
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
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
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
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/param.h>
33 
34 #include <powerpc/psl.h>
35 #include <powerpc/oea/spr.h>
36 
37 #include <lib/libsa/stand.h>
38 #include <lib/libsa/net.h>
39 #include <lib/libkern/libkern.h>
40 
41 #include <machine/bootinfo.h>
42 
43 #include "globals.h"
44 
45 #define BRD_DECL(xxx) \
46     void xxx ## setup(struct brdprop *); \
47     void xxx ## brdfix(struct brdprop *); \
48     void xxx ## pcifix(struct brdprop *); \
49     void xxx ## launch(struct brdprop *); \
50     void xxx ## reset(void)
51 
52 BRD_DECL(mot);
53 BRD_DECL(enc);
54 BRD_DECL(kuro);
55 BRD_DECL(syno);
56 BRD_DECL(qnap);
57 BRD_DECL(iomega);
58 BRD_DECL(dlink);
59 BRD_DECL(nhnas);
60 BRD_DECL(kurot4);
61 
62 static void brdfixup(void);
63 static void setup(void);
64 static void send_iomega(int, int, int, int, int, int);
65 static inline uint32_t mfmsr(void);
66 static inline void mtmsr(uint32_t);
67 static inline uint32_t cputype(void);
68 static inline uint64_t mftb(void);
69 static void init_uart(unsigned, unsigned, uint8_t);
70 static void send_sat(char *);
71 static unsigned mpc107memsize(void);
72 
73 /* UART registers */
74 #define RBR		0
75 #define THR		0
76 #define DLB		0
77 #define DMB		1
78 #define IER		1
79 #define FCR		2
80 #define LCR		3
81 #define  LCR_DLAB	0x80
82 #define  LCR_PEVEN	0x18
83 #define  LCR_PNONE	0x00
84 #define  LCR_8BITS	0x03
85 #define MCR		4
86 #define  MCR_RTS	0x02
87 #define  MCR_DTR	0x01
88 #define LSR		5
89 #define  LSR_THRE	0x20
90 #define  LSR_DRDY	0x01
91 #define DCR		0x11
92 #define UART_READ(base, r)	in8(base + (r))
93 #define UART_WRITE(base, r, v)	out8(base + (r), (v))
94 
95 /* MPC106 and MPC824x PCI bridge memory configuration */
96 #define MPC106_MEMSTARTADDR1	0x80
97 #define MPC106_EXTMEMSTARTADDR1	0x88
98 #define MPC106_MEMENDADDR1	0x90
99 #define MPC106_EXTMEMENDADDR1	0x98
100 #define MPC106_MEMEN		0xa0
101 
102 /* Iomega StorCenter MC68HC908 microcontroller data packet */
103 #define IOMEGA_POWER		0
104 #define IOMEGA_LED		1
105 #define IOMEGA_FLASH_RATE	2
106 #define IOMEGA_FAN		3
107 #define IOMEGA_HIGH_TEMP	4
108 #define IOMEGA_LOW_TEMP		5
109 #define IOMEGA_ID		6
110 #define IOMEGA_CHECKSUM		7
111 #define IOMEGA_PACKETSIZE	8
112 
113 /* NH230/231 GPIO */
114 #define NHGPIO_WRITE(x)		*((volatile uint8_t *)0x70000000) = (x)
115 
116 /* Synology CPLD (2007 and newer models) */
117 #define SYNOCPLD_READ(r)	*((volatile uint8_t *)0xff000000 + (r))
118 #define SYNOCPLD_WRITE(r,x)	do { \
119     *((volatile uint8_t *)0xff000000 + (r)) = (x); \
120     delay(10); \
121     } while(0)
122 
123 static struct brdprop brdlist[] = {
124     {
125 	"sandpoint",
126 	"Sandpoint X3",
127 	BRD_SANDPOINTX3,
128 	0,
129 	"com", 0x3f8, 115200,
130 	motsetup, motbrdfix, motpcifix, NULL, NULL },
131     {
132 	"encpp1",
133 	"EnCore PP1",
134 	BRD_ENCOREPP1,
135 	0,
136 	"com", 0x3f8, 115200,
137 	encsetup, encbrdfix, encpcifix, NULL, NULL },
138     {
139 	"kurobox",
140 	"KuroBox",
141 	BRD_KUROBOX,
142 	0,
143 	"eumb", 0x4600, 57600,
144 	kurosetup, kurobrdfix, NULL, NULL, kuroreset },
145     {
146 	"synology",
147 	"Synology CS/DS/RS",
148 	BRD_SYNOLOGY,
149 	0,
150 	"eumb", 0x4500, 115200,
151 	synosetup, synobrdfix, synopcifix, synolaunch, synoreset },
152     {
153 	"qnap",
154 	"QNAP TS",
155 	BRD_QNAPTS,
156 	33164691,	/* Linux source says 33000000, but the Synology  */
157 			/* clock value delivers a much better precision. */
158 	"eumb", 0x4500, 115200,
159 	NULL, qnapbrdfix, NULL, NULL, qnapreset },
160     {
161 	"iomega",
162 	"IOMEGA StorCenter G2",
163 	BRD_STORCENTER,
164 	0,
165 	"eumb", 0x4500, 115200,
166 	NULL, iomegabrdfix, NULL, NULL, iomegareset },
167     {
168 	"dlink",
169 	"D-Link DSM-G600",
170 	BRD_DLINKDSM,
171 	33000000,
172 	"eumb", 0x4500, 9600,
173 	NULL, dlinkbrdfix, NULL, NULL, NULL },
174     {
175 	"nhnas",
176 	"Netronix NH-230/231",
177 	BRD_NH230NAS,
178 	33000000,
179 	"eumb", 0x4500, 9600,
180 	NULL, nhnasbrdfix, NULL, NULL, nhnasreset },
181     {
182 	"kurot4",
183 	"KuroBox/T4",
184 	BRD_KUROBOXT4,
185 	32768000,
186 	"eumb", 0x4600, 57600,
187 	NULL, kurot4brdfix, NULL, NULL, NULL },
188     {
189 	"unknown",
190 	"Unknown board",
191 	BRD_UNKNOWN,
192 	0,
193 	"eumb", 0x4500, 115200,
194 	NULL, NULL, NULL, NULL, NULL }, /* must be the last */
195 };
196 
197 static struct brdprop *brdprop;
198 static uint32_t ticks_per_sec, ns_per_tick;
199 
200 const unsigned dcache_line_size = 32;		/* 32B linesize */
201 const unsigned dcache_range_size = 4 * 1024;	/* 16KB / 4-way */
202 
203 unsigned uart1base;	/* console */
204 unsigned uart2base;	/* optional satellite processor */
205 
206 void brdsetup(void);	/* called by entry.S */
207 
208 void
brdsetup(void)209 brdsetup(void)
210 {
211 	static uint8_t pci_to_memclk[] = {
212 		30, 30, 10, 10, 20, 10, 10, 10,
213 		10, 20, 20, 15, 20, 15, 20, 30,
214 		30, 40, 15, 40, 20, 25, 20, 40,
215 		25, 20, 10, 20, 15, 15, 20, 00
216 	};
217 	static uint8_t mem_to_cpuclk[] = {
218 		25, 30, 45, 20, 20, 00, 10, 30,
219 		30, 20, 45, 30, 25, 35, 30, 35,
220 		20, 25, 20, 30, 35, 40, 40, 20,
221 		30, 25, 40, 30, 30, 25, 35, 00
222 	};
223 	char *consname;
224 	int consport;
225 	uint32_t extclk;
226 	unsigned pchb, pcib, dev11, dev12, dev13, dev15, dev16, val;
227 	extern struct btinfo_memory bi_mem;
228 	extern struct btinfo_console bi_cons;
229 	extern struct btinfo_clock bi_clk;
230 	extern struct btinfo_prodfamily bi_fam;
231 
232 	/*
233 	 * CHRP specification "Map-B" BAT012 layout
234 	 *   BAT0 0000-0000 (256MB) SDRAM
235 	 *   BAT1 8000-0000 (256MB) PCI mem space
236 	 *   BAT2 fc00-0000 (64MB)  EUMB, PCI I/O space, misc devs, flash
237 	 *
238 	 * EUMBBAR is at fc00-0000.
239 	 */
240 	pchb = pcimaketag(0, 0, 0);
241 	pcicfgwrite(pchb, 0x78, 0xfc000000);
242 
243 	brdtype = BRD_UNKNOWN;
244 	extclk = EXT_CLK_FREQ;	/* usually 33MHz */
245 	busclock = 0;
246 
247 	dev11 = pcimaketag(0, 11, 0);
248 	dev12 = pcimaketag(0, 12, 0);
249 	dev13 = pcimaketag(0, 13, 0);
250 	dev15 = pcimaketag(0, 15, 0);
251 	dev16 = pcimaketag(0, 16, 0);
252 
253 	if (pcifinddev(0x10ad, 0x0565, &pcib) == 0) {
254 		/* WinBond 553 southbridge at dev 11 */
255 		brdtype = BRD_SANDPOINTX3;
256 	}
257 	else if (pcifinddev(0x1106, 0x0686, &pcib) == 0) {
258 		/* VIA 686B southbridge at dev 22 */
259 		brdtype = BRD_ENCOREPP1;
260 	}
261 	else if (PCI_CLASS(pcicfgread(dev11, PCI_CLASS_REG)) == PCI_CLASS_ETH) {
262 		/* ADMtek AN985 (tlp) or RealTek 8169S (re) at dev 11 */
263 		if (PCI_VENDOR(pcicfgread(dev11, PCI_ID_REG)) == 0x1317)
264 			brdtype = BRD_KUROBOX;
265 		else if (PCI_VENDOR(pcicfgread(dev11, PCI_ID_REG)) == 0x10ec) {
266 			if (PCI_PRODUCT(pcicfgread(dev12,PCI_ID_REG)) != 0x3512)
267 				brdtype = BRD_KUROBOX;
268 			else
269 				brdtype = BRD_KUROBOXT4;
270 		}
271 	}
272 	else if (PCI_VENDOR(pcicfgread(dev15, PCI_ID_REG)) == 0x1148
273 	    || PCI_VENDOR(pcicfgread(dev15, PCI_ID_REG)) == 0x11ab) {
274 		/* SKnet/Marvell (sk) at dev 15 */
275 		brdtype = BRD_SYNOLOGY;
276 	}
277 	else if (PCI_VENDOR(pcicfgread(dev13, PCI_ID_REG)) == 0x1106) {
278 		/* VIA 6410 (viaide) at dev 13 */
279 		brdtype = BRD_STORCENTER;
280 	}
281 	else if (PCI_VENDOR(pcicfgread(dev16, PCI_ID_REG)) == 0x1191) {
282 		/* ACARD ATP865 (acardide) at dev 16 */
283 		brdtype = BRD_DLINKDSM;
284 	}
285 	else if (PCI_VENDOR(pcicfgread(dev16, PCI_ID_REG)) == 0x1283
286 	    || PCI_VENDOR(pcicfgread(dev16, PCI_ID_REG)) == 0x1095) {
287 		/* ITE (iteide) or SiI (satalink) at dev 16 */
288 		brdtype = BRD_NH230NAS;
289 	}
290 	else if (PCI_VENDOR(pcicfgread(dev15, PCI_ID_REG)) == 0x8086
291 	    || PCI_VENDOR(pcicfgread(dev15, PCI_ID_REG)) == 0x10ec) {
292 		/* Intel (wm) or RealTek (re) at dev 15 */
293 		brdtype = BRD_QNAPTS;
294 	}
295 
296 	brdprop = brd_lookup(brdtype);
297 
298 	/* brd dependent adjustments */
299 	setup();
300 
301 	/* determine clock frequencies */
302 	if (brdprop->extclk != 0)
303 		extclk = brdprop->extclk;
304 	if (busclock == 0) {
305 		if (cputype() == MPC8245) {
306 			/* PLL_CFG from PCI host bridge register 0xe2 */
307 			val = pcicfgread(pchb, 0xe0);
308 			busclock = (extclk *
309 			    pci_to_memclk[(val >> 19) & 0x1f] + 10) / 10;
310 			/* PLLRATIO from HID1 */
311 			asm volatile ("mfspr %0,1009" : "=r"(val));
312 			cpuclock = ((uint64_t)busclock *
313 			    mem_to_cpuclk[val >> 27] + 10) / 10;
314 		} else
315 			busclock = 100000000;	/* 100MHz bus clock default */
316 	}
317 	ticks_per_sec = busclock >> 2;
318 	ns_per_tick = 1000000000 / ticks_per_sec;
319 
320 	/* now prepare serial console */
321 	consname = brdprop->consname;
322 	consport = brdprop->consport;
323 	if (strcmp(consname, "eumb") == 0) {
324 		uart1base = 0xfc000000 + consport;	/* 0x4500, 0x4600 */
325 		UART_WRITE(uart1base, DCR, 0x01);	/* enable DUART mode */
326 		uart2base = uart1base ^ 0x0300;
327 	} else
328 		uart1base = 0xfe000000 + consport;	/* 0x3f8, 0x2f8 */
329 
330 	/* more brd adjustments */
331 	brdfixup();
332 
333 	bi_mem.memsize = mpc107memsize();
334 	snprintf(bi_cons.devname, sizeof(bi_cons.devname), "%s", consname);
335 	bi_cons.addr = consport;
336 	bi_cons.speed = brdprop->consspeed;
337 	bi_clk.ticks_per_sec = ticks_per_sec;
338 	snprintf(bi_fam.name, sizeof(bi_fam.name), "%s", brdprop->family);
339 }
340 
341 struct brdprop *
brd_lookup(int brd)342 brd_lookup(int brd)
343 {
344 	u_int i;
345 
346 	for (i = 0; i < sizeof(brdlist)/sizeof(brdlist[0]); i++) {
347 		if (brdlist[i].brdtype == brd)
348 			return &brdlist[i];
349 	}
350 	return &brdlist[i - 1];
351 }
352 
353 static void
setup()354 setup()
355 {
356 
357 	if (brdprop->setup == NULL)
358 		return;
359 	(*brdprop->setup)(brdprop);
360 }
361 
362 static void
brdfixup()363 brdfixup()
364 {
365 
366 	if (brdprop->brdfix == NULL)
367 		return;
368 	(*brdprop->brdfix)(brdprop);
369 }
370 
371 void
pcifixup()372 pcifixup()
373 {
374 
375 	if (brdprop->pcifix == NULL)
376 		return;
377 	(*brdprop->pcifix)(brdprop);
378 }
379 
380 void
launchfixup()381 launchfixup()
382 {
383 
384 	if (brdprop->launch == NULL)
385 		return;
386 	(*brdprop->launch)(brdprop);
387 }
388 
389 void
encsetup(struct brdprop * brd)390 encsetup(struct brdprop *brd)
391 {
392 
393 #ifdef COSNAME
394 	brd->consname = CONSNAME;
395 #endif
396 #ifdef CONSPORT
397 	brd->consport = CONSPORT;
398 #endif
399 #ifdef CONSSPEED
400 	brd->consspeed = CONSSPEED;
401 #endif
402 }
403 
404 void
encbrdfix(struct brdprop * brd)405 encbrdfix(struct brdprop *brd)
406 {
407 	unsigned ac97, ide, pcib, pmgt, usb12, usb34, val;
408 
409 /*
410  * VIA82C686B Southbridge
411  *	0.22.0	1106.0686	PCI-ISA bridge
412  *	0.22.1	1106.0571	IDE (viaide)
413  *	0.22.2	1106.3038	USB 0/1 (uhci)
414  *	0.22.3	1106.3038	USB 2/3 (uhci)
415  *	0.22.4	1106.3057	power management
416  *	0.22.5	1106.3058	AC97 (auvia)
417  */
418 	pcib  = pcimaketag(0, 22, 0);
419 	ide   = pcimaketag(0, 22, 1);
420 	usb12 = pcimaketag(0, 22, 2);
421 	usb34 = pcimaketag(0, 22, 3);
422 	pmgt  = pcimaketag(0, 22, 4);
423 	ac97  = pcimaketag(0, 22, 5);
424 
425 #define	CFG(i,v) do { \
426    *(volatile unsigned char *)(0xfe000000 + 0x3f0) = (i); \
427    *(volatile unsigned char *)(0xfe000000 + 0x3f1) = (v); \
428    } while (0)
429 	val = pcicfgread(pcib, 0x84);
430 	val |= (02 << 8);
431 	pcicfgwrite(pcib, 0x84, val);
432 	CFG(0xe2, 0x0f); /* use COM1/2, don't use FDC/LPT */
433 	val = pcicfgread(pcib, 0x84);
434 	val &= ~(02 << 8);
435 	pcicfgwrite(pcib, 0x84, val);
436 
437 	/* route pin C to i8259 IRQ 5, pin D to 11 */
438 	val = pcicfgread(pcib, 0x54);
439 	val = (val & 0xff) | 0xb0500000; /* Dx CB Ax xS */
440 	pcicfgwrite(pcib, 0x54, val);
441 
442 	/* enable EISA ELCR1 (0x4d0) and ELCR2 (0x4d1) */
443 	val = pcicfgread(pcib, 0x44);
444 	val = val | 0x20000000;
445 	pcicfgwrite(pcib, 0x44, val);
446 
447 	/* select level trigger for IRQ 5/11 at ELCR1/2 */
448 	*(volatile uint8_t *)0xfe0004d0 = 0x20; /* bit 5 */
449 	*(volatile uint8_t *)0xfe0004d1 = 0x08; /* bit 11 */
450 
451 	/* USB and AC97 are hardwired with pin D and C */
452 	val = pcicfgread(usb12, 0x3c) &~ 0xff;
453 	val |= 11;
454 	pcicfgwrite(usb12, 0x3c, val);
455 	val = pcicfgread(usb34, 0x3c) &~ 0xff;
456 	val |= 11;
457 	pcicfgwrite(usb34, 0x3c, val);
458 	val = pcicfgread(ac97, 0x3c) &~ 0xff;
459 	val |= 5;
460 	pcicfgwrite(ac97, 0x3c, val);
461 
462 	(void) pcicfgread(ide, 0x08);
463 	(void) pcicfgread(pmgt, 0x08);
464 }
465 
466 void
encpcifix(struct brdprop * brd)467 encpcifix(struct brdprop *brd)
468 {
469 	unsigned ide, irq, net, pcib, steer, val;
470 
471 #define	STEER(v, b) (((v) & (b)) ? "edge" : "level")
472 	pcib = pcimaketag(0, 22, 0);
473 	ide  = pcimaketag(0, 22, 1);
474 	net  = pcimaketag(0, 25, 0);
475 
476 	/*
477 	 * //// VIA PIRQ ////
478 	 * 0x57/56/55/54 - Dx CB Ax xS
479 	 */
480 	val = pcicfgread(pcib, 0x54);	/* Dx CB Ax xs */
481 	steer = val & 0xf;
482 	irq = (val >> 12) & 0xf;	/* 15:12 */
483 	if (irq) {
484 		printf("pin A -> irq %d, %s\n",
485 			irq, STEER(steer, 0x1));
486 	}
487 	irq = (val >> 16) & 0xf;	/* 19:16 */
488 	if (irq) {
489 		printf("pin B -> irq %d, %s\n",
490 			irq, STEER(steer, 0x2));
491 	}
492 	irq = (val >> 20) & 0xf;	/* 23:20 */
493 	if (irq) {
494 		printf("pin C -> irq %d, %s\n",
495 			irq, STEER(steer, 0x4));
496 	}
497 	irq = (val >> 28);		/* 31:28 */
498 	if (irq) {
499 		printf("pin D -> irq %d, %s\n",
500 			irq, STEER(steer, 0x8));
501 	}
502 #if 0
503 	/*
504 	 * //// IDE fixup ////
505 	 * - "native mode" (ide 0x09)
506 	 */
507 
508 	/* ide: 0x09 - programming interface; 1000'SsPp */
509 	val = pcicfgread(ide, 0x08) & 0xffff00ff;
510 	pcicfgwrite(ide, 0x08, val | (0x8f << 8));
511 
512 	/* ide: 0x10-20 - leave them PCI memory space assigned */
513 #else
514 	/*
515 	 * //// IDE fixup ////
516 	 * - "compatibility mode" (ide 0x09)
517 	 * - remove PCI pin assignment (ide 0x3d)
518 	 */
519 
520 	/* ide: 0x09 - programming interface; 1000'SsPp */
521 	val = pcicfgread(ide, 0x08) & 0xffff00ff;
522 	val |= (0x8a << 8);
523 	pcicfgwrite(ide, 0x08, val);
524 
525 	/* ide: 0x10-20 */
526 	/*
527 	 * experiment shows writing ide: 0x09 changes these
528 	 * register behaviour. The pcicfgwrite() above writes
529 	 * 0x8a at ide: 0x09 to make sure legacy IDE.  Then
530 	 * reading BAR0-3 is to return value 0s even though
531 	 * pcisetup() has written range assignments.  Value
532 	 * overwrite makes no effect. Having 0x8f for native
533 	 * PCIIDE doesn't change register values and brings no
534 	 * weirdness.
535 	 */
536 
537 	/* ide: 0x3d/3c - turn off PCI pin */
538 	val = pcicfgread(ide, 0x3c) & 0xffff00ff;
539 	pcicfgwrite(ide, 0x3c, val);
540 #endif
541 	/*
542 	 * //// USBx2, audio, and modem fixup ////
543 	 * - disable USB #0 and #1 (pcib 0x48 and 0x85)
544 	 * - disable AC97 audio and MC97 modem (pcib 0x85)
545 	 */
546 
547 	/* pcib: 0x48 - disable USB #0 at function 2 */
548 	val = pcicfgread(pcib, 0x48);
549 	pcicfgwrite(pcib, 0x48, val | 04);
550 
551 	/* pcib: 0x85 - disable USB #1 at function 3 */
552 	/* pcib: 0x85 - disable AC97/MC97 at function 5/6 */
553 	val = pcicfgread(pcib, 0x84);
554 	pcicfgwrite(pcib, 0x84, val | 0x1c00);
555 
556 	/*
557 	 * //// fxp fixup ////
558 	 * - use PCI pin A line 25 (fxp 0x3d/3c)
559 	 */
560 	/* 0x3d/3c - PCI pin/line */
561 	val = pcicfgread(net, 0x3c) & 0xffff0000;
562 	val |= (('A' - '@') << 8) | 25;
563 	pcicfgwrite(net, 0x3c, val);
564 }
565 
566 void
motsetup(struct brdprop * brd)567 motsetup(struct brdprop *brd)
568 {
569 
570 #ifdef COSNAME
571 	brd->consname = CONSNAME;
572 #endif
573 #ifdef CONSPORT
574 	brd->consport = CONSPORT;
575 #endif
576 #ifdef CONSSPEED
577 	brd->consspeed = CONSSPEED;
578 #endif
579 }
580 
581 void
motbrdfix(struct brdprop * brd)582 motbrdfix(struct brdprop *brd)
583 {
584 
585 /*
586  * WinBond/Symphony Lab 83C553 with PC87308 "SuperIO"
587  *
588  *	0.11.0	10ad.0565	PCI-ISA bridge
589  *	0.11.1	10ad.0105	IDE (slide)
590  */
591 }
592 
593 void
motpcifix(struct brdprop * brd)594 motpcifix(struct brdprop *brd)
595 {
596 	unsigned ide, net, pcib, steer, val;
597 	int line;
598 
599 	pcib = pcimaketag(0, 11, 0);
600 	ide  = pcimaketag(0, 11, 1);
601 	net  = pcimaketag(0, 15, 0);
602 
603 	/*
604 	 * //// WinBond PIRQ ////
605 	 * 0x40 - bit 5 (0x20) indicates PIRQ presense
606 	 * 0x60 - PIRQ interrupt routing steer
607 	 */
608 	if (pcicfgread(pcib, 0x40) & 0x20) {
609 		steer = pcicfgread(pcib, 0x60);
610 		if ((steer & 0x80808080) == 0x80808080)
611 			printf("PIRQ[0-3] disabled\n");
612 		else {
613 			unsigned i, v = steer;
614 			for (i = 0; i < 4; i++, v >>= 8) {
615 				if ((v & 0x80) != 0 || (v & 0xf) == 0)
616 					continue;
617 				printf("PIRQ[%d]=%d\n", i, v & 0xf);
618 				}
619 			}
620 		}
621 #if 1
622 	/*
623 	 * //// IDE fixup -- case A ////
624 	 * - "native PCI mode" (ide 0x09)
625 	 * - don't use ISA IRQ14/15 (pcib 0x43)
626 	 * - native IDE for both channels (ide 0x40)
627 	 * - LEGIRQ bit 11 steers interrupt to pin C (ide 0x40)
628 	 * - sign as PCI pin C line 11 (ide 0x3d/3c)
629 	 */
630 	/* ide: 0x09 - programming interface; 1000'SsPp */
631 	val = pcicfgread(ide, 0x08);
632 	val &= 0xffff00ff;
633 	pcicfgwrite(ide, 0x08, val | (0x8f << 8));
634 
635 	/* pcib: 0x43 - IDE interrupt routing */
636 	val = pcicfgread(pcib, 0x40) & 0x00ffffff;
637 	pcicfgwrite(pcib, 0x40, val);
638 
639 	/* pcib: 0x45/44 - PCI interrupt routing */
640 	val = pcicfgread(pcib, 0x44) & 0xffff0000;
641 	pcicfgwrite(pcib, 0x44, val);
642 
643 	/* ide: 0x41/40 - IDE channel */
644 	val = pcicfgread(ide, 0x40) & 0xffff0000;
645 	val |= (1 << 11) | 0x33; /* LEGIRQ turns on PCI interrupt */
646 	pcicfgwrite(ide, 0x40, val);
647 
648 	/* ide: 0x3d/3c - use PCI pin C/line 11 */
649 	val = pcicfgread(ide, 0x3c) & 0xffffff00;
650 	val |= 11; /* pin designation is hardwired to pin A */
651 	pcicfgwrite(ide, 0x3c, val);
652 #else
653 	/*
654 	 * //// IDE fixup -- case B ////
655 	 * - "compatibility mode" (ide 0x09)
656 	 * - IDE primary/secondary interrupt routing (pcib 0x43)
657 	 * - PCI interrupt routing (pcib 0x45/44)
658 	 * - no PCI pin/line assignment (ide 0x3d/3c)
659 	 */
660 	/* ide: 0x09 - programming interface; 1000'SsPp */
661 	val = pcicfgread(ide, 0x08);
662 	val &= 0xffff00ff;
663 	pcicfgwrite(ide, 0x08, val | (0x8a << 8));
664 
665 	/* pcib: 0x43 - IDE interrupt routing */
666 	val = pcicfgread(pcib, 0x40) & 0x00ffffff;
667 	pcicfgwrite(pcib, 0x40, val | (0xee << 24));
668 
669 	/* ide: 0x45/44 - PCI interrupt routing */
670 	val = pcicfgread(ide, 0x44) & 0xffff0000;
671 	pcicfgwrite(ide, 0x44, val);
672 
673 	/* ide: 0x3d/3c - turn off PCI pin/line */
674 	val = pcicfgread(ide, 0x3c) & 0xffff0000;
675 	pcicfgwrite(ide, 0x3c, val);
676 #endif
677 
678 	/*
679 	 * //// fxp fixup ////
680 	 * - use PCI pin A line 15 (fxp 0x3d/3c)
681 	 */
682 	val = pcicfgread(net, 0x3c) & 0xffff0000;
683 	pcidecomposetag(net, NULL, &line, NULL);
684 	val |= (('A' - '@') << 8) | line;
685 	pcicfgwrite(net, 0x3c, val);
686 }
687 
688 void
kurosetup(struct brdprop * brd)689 kurosetup(struct brdprop *brd)
690 {
691 
692 	if (PCI_VENDOR(pcicfgread(pcimaketag(0, 11, 0), PCI_ID_REG)) == 0x10ec)
693 		brd->extclk = 32768000; /* decr 2457600Hz */
694 	else
695 		brd->extclk = 32521333; /* decr 2439100Hz */
696 }
697 
698 void
kurobrdfix(struct brdprop * brd)699 kurobrdfix(struct brdprop *brd)
700 {
701 
702 	init_uart(uart2base, 9600, LCR_8BITS | LCR_PEVEN);
703 	/* Stop Watchdog */
704 	send_sat("AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK");
705 }
706 
707 void
kuroreset()708 kuroreset()
709 {
710 
711 	send_sat("CCGG");
712 	/*NOTREACHED*/
713 }
714 
715 void
synosetup(struct brdprop * brd)716 synosetup(struct brdprop *brd)
717 {
718 
719 	if (1) /* 200 and 266MHz models */
720 		brd->extclk = 33164691; /* from Synology/Linux source */
721 	else   /* 400MHz models XXX how to check? */
722 		brd->extclk = 33165343;
723 }
724 
725 void
synobrdfix(struct brdprop * brd)726 synobrdfix(struct brdprop *brd)
727 {
728 
729 	init_uart(uart2base, 9600, LCR_8BITS | LCR_PNONE);
730 	/* beep, power LED on, status LED off */
731 	send_sat("247");
732 }
733 
734 #define SYNO_FAN_TIMEOUT	500	/* 500ms to turn the fan off */
735 #define SYNO_DISK_DELAY		30	/* 30 seconds to power up 2nd disk */
736 
737 void
synopcifix(struct brdprop * brd)738 synopcifix(struct brdprop *brd)
739 {
740 	static const char models207[4][7] = {
741 		"???", "DS107e", "DS107", "DS207"
742 	};
743 	static const char models209[2][7] = {
744 		"DS109j", "DS209j"
745 	};
746 	static const char models406[3][7] = {
747 		"CS406e", "CS406", "RS406"
748 	};
749 	static const char models407[4][7] = {
750 		"???", "CS407e", "CS407", "RS407"
751 	};
752 	extern struct btinfo_model bi_model;
753 	const char *model_name;
754 	unsigned cpld, version, flags;
755 	uint8_t v, status;
756 	int i;
757 
758 	/*
759 	 * Determine if a CPLD is present and whether is has 4-bit
760 	 * (models 107, 207, 209)  or 8-bit (models 406, 407) registers.
761 	 * The register set repeats every 16 bytes.
762 	 */
763 	cpld = 0;
764 	flags = 0;
765 	version = 0;
766 	model_name = NULL;
767 
768 	SYNOCPLD_WRITE(0, 0x00);	/* LEDs blinking yellow (default) */
769 	v = SYNOCPLD_READ(0);
770 
771 	if (v != 0x00) {
772 		v &= 0xf0;
773 		if (v != 0x00 || (SYNOCPLD_READ(16 + 0) & 0xf0) != v)
774 			goto cpld_done;
775 
776   cpld4bits:
777 		/* 4-bit registers assumed, make LEDs solid yellow */
778 		SYNOCPLD_WRITE(0, 0x50);
779 		v = SYNOCPLD_READ(0) & 0xf0;
780 		if (v != 0x50 || (SYNOCPLD_READ(32 + 0) & 0xf0) != v)
781 			goto cpld_done;
782 
783 		v = SYNOCPLD_READ(2) & 0xf0;
784 		if ((SYNOCPLD_READ(48 + 2) & 0xf0) != v)
785 			goto cpld_done;
786 		version = (v >> 4) & 7;
787 
788 		/*
789 		 * Try to determine whether it is a 207-style or 209-style
790 		 * CPLD register set, by turning the fan off and check if
791 		 * either bit 5 or bit 4 changes from 0 to 1 to indicate
792 		 * the fan is stopped.
793 		 */
794 		status = SYNOCPLD_READ(3) & 0xf0;
795 		SYNOCPLD_WRITE(3, 0x00);	/* fan off */
796 
797 		for (i = 0; i < SYNO_FAN_TIMEOUT * 100; i++) {
798 			delay(10);
799 			v = SYNOCPLD_READ(3) & 0xf0;
800 			if ((status & 0x20) == 0 && (v & 0x20) != 0) {
801 				/* set x07 model */
802 				v = SYNOCPLD_READ(1) >> 6;
803 				model_name = models207[v];
804 				cpld = BI_MODEL_CPLD207;
805 				/* XXXX DS107v2/v3 have no thermal sensor */
806 				flags |= BI_MODEL_THERMAL;
807 				break;
808 			}
809 			if ((status & 0x10) == 0 && (v & 0x10) != 0) {
810 				/* set x09 model */
811 				v = SYNOCPLD_READ(1) >> 7;
812 				model_name = models209[v];
813 				cpld = BI_MODEL_CPLD209;
814 				if (v == 1)	/* DS209j */
815 					flags |= BI_MODEL_THERMAL;
816 				break;
817 			}
818 			/* XXX What about DS108j? Does it have a CPLD? */
819 		}
820 
821 		/* turn the fan on again */
822 		SYNOCPLD_WRITE(3, status);
823 
824 		if (i >= SYNO_FAN_TIMEOUT * 100)
825 			goto cpld_done;		/* timeout: no valid CPLD */
826 	} else {
827 		if (SYNOCPLD_READ(16 + 0) != v)
828 			goto cpld4bits;
829 
830 		/* 8-bit registers assumed, make LEDs solid yellow */
831 		SYNOCPLD_WRITE(0, 0x55);
832 		v = SYNOCPLD_READ(0);
833 		if (v != 0x55)
834 			goto cpld4bits;		/* try 4 bits instead */
835 		if (SYNOCPLD_READ(32 + 0) != v)
836 			goto cpld_done;
837 
838 		v = SYNOCPLD_READ(2);
839 		if (SYNOCPLD_READ(48 + 2) != v)
840 			goto cpld_done;
841 		version = v & 3;
842 
843 		if ((v & 0x0c) != 0x0c) {
844 			/* set 406 model */
845 			model_name = models406[(v >> 2) & 3];
846 			cpld = BI_MODEL_CPLD406;
847 		} else {
848 			/* set 407 model */
849 			model_name = models407[v >> 6];
850 			cpld = BI_MODEL_CPLD407;
851 			flags |= BI_MODEL_THERMAL;
852 		}
853 	}
854 
855 	printf("CPLD V%s%u detected for model %s\n",
856 	    cpld < BI_MODEL_CPLD406 ? "" : "1.",
857 	    version, model_name);
858 
859 	if (cpld ==  BI_MODEL_CPLD406 || cpld ==  BI_MODEL_CPLD407) {
860 		/*
861 		 * CS/RS stations power-up their disks one after another.
862 		 * We have to watch over the current power state in a CPLD
863 		 * register, until all disks become available.
864 		 */
865 		do {
866 			delay(1000 * 1000);
867 			v = SYNOCPLD_READ(1);
868 			printf("Power state: %02x\r", v);
869 		} while (v != 0xff);
870 		putchar('\n');
871 	} else if (model_name != NULL && model_name[2] == '2') {
872 		/*
873 		 * DS207 and DS209 have a second SATA disk, which is started
874 		 * with several seconds delay, but no CPLD register to
875 		 * monitor the power state. So all we can do is to
876 		 * wait some more seconds during SATA-init.
877 		 * Also wait some seconds now, to make sure the first
878 		 * disk is ready after a cold start.
879 		 */
880 		sata_delay[1] = SYNO_DISK_DELAY;
881 		delay(10 * 1024 * 1024);
882 	}
883 
884   cpld_done:
885 	if (model_name != NULL) {
886 		snprintf(bi_model.name, sizeof(bi_model.name), "%s", model_name);
887 		bi_model.flags = cpld | version | flags;
888 	} else
889 		printf("No CPLD found. DS101/DS106.\n");
890 }
891 
892 void
synolaunch(struct brdprop * brd)893 synolaunch(struct brdprop *brd)
894 {
895 	extern struct btinfo_model bi_model;
896 	struct dkdev_ata *sata1, *sata2;
897 	unsigned cpld;
898 
899 	cpld = bi_model.flags & BI_MODEL_CPLD_MASK;
900 
901 	if (cpld ==  BI_MODEL_CPLD406 || cpld ==  BI_MODEL_CPLD407) {
902 		/* set drive LEDs for active disk drives on CS/RS models */
903 		sata1 = lata[0].drv;
904 		sata2 = lata[1].drv;
905 		SYNOCPLD_WRITE(0, (sata1->presense[0] ? 0x80 : 0xc0) |
906 		    (sata1->presense[1] ? 0x20 : 0x30) |
907 		    (sata2->presense[0] ? 0x08 : 0x0c) |
908 		    (sata2->presense[1] ? 0x02 : 0x03));
909 	} else if (cpld ==  BI_MODEL_CPLD207 || cpld ==  BI_MODEL_CPLD209) {
910 		/* set drive LEDs for DS207 and DS209 models */
911 		sata1 = lata[0].drv;
912 		SYNOCPLD_WRITE(0, (sata1->presense[0] ? 0x80 : 0xc0) |
913 		    (sata1->presense[1] ? 0x20 : 0x30));
914 	}
915 }
916 
917 void
synoreset()918 synoreset()
919 {
920 
921 	send_sat("C");
922 	/*NOTREACHED*/
923 }
924 
925 void
qnapbrdfix(struct brdprop * brd)926 qnapbrdfix(struct brdprop *brd)
927 {
928 
929 	init_uart(uart2base, 19200, LCR_8BITS | LCR_PNONE);
930 	/* beep, status LED red */
931 	send_sat("PW");
932 }
933 
934 void
qnapreset()935 qnapreset()
936 {
937 
938 	send_sat("f");
939 	/*NOTREACHED*/
940 }
941 
942 void
iomegabrdfix(struct brdprop * brd)943 iomegabrdfix(struct brdprop *brd)
944 {
945 
946 	init_uart(uart2base, 9600, LCR_8BITS | LCR_PNONE);
947 	/* LED flashing blue, fan auto, turn on at 50C, turn off at 45C */
948 	send_iomega('b', 'd', 2, 'a', 50, 45);
949 }
950 
951 void
iomegareset()952 iomegareset()
953 {
954 
955 	send_iomega('g', 0, 0, 0, 0, 0);
956 	/*NOTREACHED*/
957 }
958 
959 void
dlinkbrdfix(struct brdprop * brd)960 dlinkbrdfix(struct brdprop *brd)
961 {
962 
963 	init_uart(uart2base, 9600, LCR_8BITS | LCR_PNONE);
964 	send_sat("SYN\n");
965 	send_sat("ZWO\n");	/* power LED solid on */
966 }
967 
968 void
nhnasbrdfix(struct brdprop * brd)969 nhnasbrdfix(struct brdprop *brd)
970 {
971 
972 	/* status LED off, USB-LEDs on, low-speed fan */
973 	NHGPIO_WRITE(0x04);
974 }
975 
976 void
nhnasreset()977 nhnasreset()
978 {
979 
980 	/* status LED on, assert system-reset to all devices */
981 	NHGPIO_WRITE(0x02);
982 	delay(100000);
983 	/*NOTREACHED*/
984 }
985 
986 void
kurot4brdfix(struct brdprop * brd)987 kurot4brdfix(struct brdprop *brd)
988 {
989 
990 	init_uart(uart2base, 38400, LCR_8BITS | LCR_PEVEN);
991 }
992 
993 void
_rtt(void)994 _rtt(void)
995 {
996 	uint32_t msr;
997 
998 	netif_shutdown_all();
999 
1000 	if (brdprop->reset != NULL)
1001 		(*brdprop->reset)();
1002 	else {
1003 		msr = mfmsr();
1004 		msr &= ~PSL_EE;
1005 		mtmsr(msr);
1006 		asm volatile ("sync; isync");
1007 		asm volatile("mtspr %0,%1" : : "K"(81), "r"(0));
1008 		msr &= ~(PSL_ME | PSL_DR | PSL_IR);
1009 		mtmsr(msr);
1010 		asm volatile ("sync; isync");
1011 		run(0, 0, 0, 0, (void *)0xFFF00100); /* reset entry */
1012 	}
1013 	__unreachable();
1014 }
1015 
1016 satime_t
getsecs(void)1017 getsecs(void)
1018 {
1019 	uint64_t tb = mftb();
1020 
1021 	return (tb / ticks_per_sec);
1022 }
1023 
1024 /*
1025  * Wait for about n microseconds (at least!).
1026  */
1027 void
delay(unsigned n)1028 delay(unsigned n)
1029 {
1030 	uint64_t tb;
1031 	uint32_t scratch, tbh, tbl;
1032 
1033 	tb = mftb();
1034 	tb += ((uint64_t)n * 1000 + ns_per_tick - 1) / ns_per_tick;
1035 	tbh = tb >> 32;
1036 	tbl = tb;
1037 	asm volatile(
1038 	    "1:	mftbu %0;"
1039 	    "	cmpw %0,%1;"
1040 	    "	blt 1b;"
1041 	    "	bgt 2f;"
1042 	    "	mftb %0;"
1043 	    "	cmpw 0, %0,%2;"
1044 	    "	blt 1b;"
1045 	    "2:"
1046 	    : "=&r"(scratch)
1047 	    : "r"(tbh), "r"(tbl)
1048 	    : "cc");
1049 }
1050 
1051 void
_wb(uint32_t adr,uint32_t siz)1052 _wb(uint32_t adr, uint32_t siz)
1053 {
1054 	uint32_t bnd;
1055 
1056 	asm volatile("eieio" ::: "memory");
1057 	for (bnd = adr + siz; adr < bnd; adr += dcache_line_size)
1058 		asm volatile("dcbst 0,%0" :: "r"(adr) : "memory");
1059 	asm volatile("sync" ::: "memory");
1060 }
1061 
1062 void
_wbinv(uint32_t adr,uint32_t siz)1063 _wbinv(uint32_t adr, uint32_t siz)
1064 {
1065 	uint32_t bnd;
1066 
1067 	asm volatile("eieio" ::: "memory");
1068 	for (bnd = adr + siz; adr < bnd; adr += dcache_line_size)
1069 		asm volatile("dcbf 0,%0" :: "r"(adr) : "memory");
1070 	asm volatile("sync");
1071 }
1072 
1073 void
_inv(uint32_t adr,uint32_t siz)1074 _inv(uint32_t adr, uint32_t siz)
1075 {
1076 	uint32_t bnd, off;
1077 
1078 	off = adr & (dcache_line_size - 1);
1079 	adr -= off;
1080 	siz += off;
1081 	asm volatile("eieio" ::: "memory");
1082 	if (off != 0) {
1083 		/* wbinv() leading unaligned dcache line */
1084 		asm volatile("dcbf 0,%0" :: "r"(adr) : "memory");
1085 		if (siz < dcache_line_size)
1086 			goto done;
1087 		adr += dcache_line_size;
1088 		siz -= dcache_line_size;
1089 	}
1090 	bnd = adr + siz;
1091 	off = bnd & (dcache_line_size - 1);
1092 	if (off != 0) {
1093 		/* wbinv() trailing unaligned dcache line */
1094 		asm volatile("dcbf 0,%0" :: "r"(bnd) : "memory"); /* it's OK */
1095 		if (siz < dcache_line_size)
1096 			goto done;
1097 		siz -= off;
1098 	}
1099 	for (bnd = adr + siz; adr < bnd; adr += dcache_line_size) {
1100 		/* inv() intermediate dcache lines if ever */
1101 		asm volatile("dcbi 0,%0" :: "r"(adr) : "memory");
1102 	}
1103   done:
1104 	asm volatile("sync" ::: "memory");
1105 }
1106 
1107 static inline uint32_t
mfmsr(void)1108 mfmsr(void)
1109 {
1110 	uint32_t msr;
1111 
1112 	asm volatile ("mfmsr %0" : "=r"(msr));
1113 	return msr;
1114 }
1115 
1116 static inline void
mtmsr(uint32_t msr)1117 mtmsr(uint32_t msr)
1118 {
1119 	asm volatile ("mtmsr %0" : : "r"(msr));
1120 }
1121 
1122 static inline uint32_t
cputype(void)1123 cputype(void)
1124 {
1125 	uint32_t pvr;
1126 
1127 	asm volatile ("mfpvr %0" : "=r"(pvr));
1128 	return pvr >> 16;
1129 }
1130 
1131 static inline uint64_t
mftb(void)1132 mftb(void)
1133 {
1134 	uint32_t scratch;
1135 	uint64_t tb;
1136 
1137 	asm ("1: mftbu %0; mftb %0+1; mftbu %1; cmpw %0,%1; bne 1b"
1138 	    : "=r"(tb), "=r"(scratch) :: "cc");
1139 	return tb;
1140 }
1141 
1142 static void
init_uart(unsigned base,unsigned speed,uint8_t lcr)1143 init_uart(unsigned base, unsigned speed, uint8_t lcr)
1144 {
1145 	unsigned div;
1146 
1147 	div = busclock / speed / 16;
1148 	UART_WRITE(base, LCR, 0x80);		/* turn on DLAB bit */
1149 	UART_WRITE(base, FCR, 0x00);
1150 	UART_WRITE(base, DMB, div >> 8);	/* set speed */
1151 	UART_WRITE(base, DLB, div & 0xff);
1152 	UART_WRITE(base, LCR, lcr);
1153 	UART_WRITE(base, FCR, 0x07);		/* FIFO on, TXRX FIFO reset */
1154 	UART_WRITE(base, IER, 0x00);		/* make sure INT disabled */
1155 }
1156 
1157 /* talk to satellite processor */
1158 static void
send_sat(char * msg)1159 send_sat(char *msg)
1160 {
1161 	unsigned savedbase;
1162 
1163 	savedbase = uart1base;
1164 	uart1base = uart2base;
1165 	while (*msg)
1166 		putchar(*msg++);
1167 	uart1base = savedbase;
1168 }
1169 
1170 #ifdef DEBUG
1171 static void
iomega_debug(const char * txt,uint8_t buf[])1172 iomega_debug(const char *txt, uint8_t buf[])
1173 {
1174 	int i;
1175 
1176 	printf("%s:", txt);
1177 	for (i = 0; i < IOMEGA_PACKETSIZE; i++)
1178 		printf(" %02x", buf[i]);
1179 	putchar('\n');
1180 }
1181 #endif /* DEBUG */
1182 
1183 static void
send_iomega(int power,int led,int rate,int fan,int high,int low)1184 send_iomega(int power, int led, int rate, int fan, int high, int low)
1185 {
1186 	uint8_t buf[IOMEGA_PACKETSIZE];
1187 	unsigned i, savedbase;
1188 
1189 	savedbase = uart1base;
1190 	uart1base = uart2base;
1191 
1192 	/* first flush the receive buffer */
1193   again:
1194 	while (tstchar())
1195 		(void)getchar();
1196 	delay(20000);
1197 	if (tstchar())
1198 		goto again;
1199 	/*
1200 	 * Now synchronize the transmitter by sending 0x00
1201 	 * until we receive a status reply.
1202 	 */
1203 	do {
1204 		putchar(0);
1205 		delay(50000);
1206 	} while (!tstchar());
1207 
1208 	for (i = 0; i < IOMEGA_PACKETSIZE; i++)
1209 		buf[i] = getchar();
1210 #ifdef DEBUG
1211 	uart1base = savedbase;
1212 	iomega_debug("68HC908 status", buf);
1213 	uart1base = uart2base;
1214 #endif
1215 
1216 	/* send command */
1217 	buf[IOMEGA_POWER] = power;
1218 	buf[IOMEGA_LED] = led;
1219 	buf[IOMEGA_FLASH_RATE] = rate;
1220 	buf[IOMEGA_FAN] = fan;
1221 	buf[IOMEGA_HIGH_TEMP] = high;
1222 	buf[IOMEGA_LOW_TEMP] = low;
1223 	buf[IOMEGA_ID] = 7;	/* host id */
1224 	buf[IOMEGA_CHECKSUM] = (buf[IOMEGA_POWER] + buf[IOMEGA_LED] +
1225 	    buf[IOMEGA_FLASH_RATE] + buf[IOMEGA_FAN] +
1226 	    buf[IOMEGA_HIGH_TEMP] + buf[IOMEGA_LOW_TEMP] +
1227 	    buf[IOMEGA_ID]) & 0x7f;
1228 #ifdef DEBUG
1229 	uart1base = savedbase;
1230 	iomega_debug("G2 sending", buf);
1231 	uart1base = uart2base;
1232 #endif
1233 	for (i = 0; i < IOMEGA_PACKETSIZE; i++)
1234 		putchar(buf[i]);
1235 
1236 	/* receive the reply */
1237 	for (i = 0; i < IOMEGA_PACKETSIZE; i++)
1238 		buf[i] = getchar();
1239 #ifdef DEBUG
1240 	uart1base = savedbase;
1241 	iomega_debug("68HC908 reply", buf);
1242 	uart1base = uart2base;
1243 #endif
1244 
1245 	if (buf[0] == '#')
1246 		goto again;  /* try again on error */
1247 	uart1base = savedbase;
1248 }
1249 
1250 void
putchar(int c)1251 putchar(int c)
1252 {
1253 	unsigned timo, lsr;
1254 
1255 	if (c == '\n')
1256 		putchar('\r');
1257 
1258 	timo = 0x00100000;
1259 	do {
1260 		lsr = UART_READ(uart1base, LSR);
1261 	} while (timo-- > 0 && (lsr & LSR_THRE) == 0);
1262 	if (timo > 0)
1263 		UART_WRITE(uart1base, THR, c);
1264 }
1265 
1266 int
getchar(void)1267 getchar(void)
1268 {
1269 	unsigned lsr;
1270 
1271 	do {
1272 		lsr = UART_READ(uart1base, LSR);
1273 	} while ((lsr & LSR_DRDY) == 0);
1274 	return UART_READ(uart1base, RBR);
1275 }
1276 
1277 int
tstchar(void)1278 tstchar(void)
1279 {
1280 
1281 	return (UART_READ(uart1base, LSR) & LSR_DRDY) != 0;
1282 }
1283 
1284 #define SAR_MASK 0x0ff00000
1285 #define SAR_SHIFT    20
1286 #define EAR_MASK 0x30000000
1287 #define EAR_SHIFT    28
1288 #define AR(v, s) ((((v) & SAR_MASK) >> SAR_SHIFT) << (s))
1289 #define XR(v, s) ((((v) & EAR_MASK) >> EAR_SHIFT) << (s))
1290 static void
set_mem_bounds(unsigned tag,unsigned bk_en,...)1291 set_mem_bounds(unsigned tag, unsigned bk_en, ...)
1292 {
1293 	unsigned mbst, mbxst, mben, mbxen;
1294 	unsigned start, end;
1295 	va_list ap;
1296 	int i, sh;
1297 
1298 	va_start(ap, bk_en);
1299 	mbst = mbxst = mben = mbxen = 0;
1300 
1301 	for (i = 0; i < 4; i++) {
1302 		if ((bk_en & (1U << i)) != 0) {
1303 			start = va_arg(ap, unsigned);
1304 			end = va_arg(ap, unsigned);
1305 		} else {
1306 			start = 0x3ff00000;
1307 			end = 0x3fffffff;
1308 		}
1309 		sh = i << 3;
1310 		mbst |= AR(start, sh);
1311 		mbxst |= XR(start, sh);
1312 		mben |= AR(end, sh);
1313 		mbxen |= XR(end, sh);
1314 	}
1315 	va_end(ap);
1316 
1317 	pcicfgwrite(tag, MPC106_MEMSTARTADDR1, mbst);
1318 	pcicfgwrite(tag, MPC106_EXTMEMSTARTADDR1, mbxst);
1319 	pcicfgwrite(tag, MPC106_MEMENDADDR1, mben);
1320 	pcicfgwrite(tag, MPC106_EXTMEMENDADDR1,	mbxen);
1321 	pcicfgwrite(tag, MPC106_MEMEN,
1322 	    (pcicfgread(tag, MPC106_MEMEN) & ~0xff) | (bk_en & 0xff));
1323 }
1324 
1325 static unsigned
mpc107memsize(void)1326 mpc107memsize(void)
1327 {
1328 	unsigned bankn, end, n, tag, val;
1329 
1330 	tag = pcimaketag(0, 0, 0);
1331 
1332 	if (brdtype == BRD_ENCOREPP1) {
1333 		/* the brd's PPCBOOT looks to have erroneous values */
1334 		set_mem_bounds(tag, 1, 0x00000000, (128 << 20) - 1);
1335 	} else if (brdtype == BRD_NH230NAS) {
1336 		/*
1337 		 * PPCBoot sets the end address to 0x7ffffff, although the
1338 		 * board has just 64MB (0x3ffffff).
1339 		 */
1340 		set_mem_bounds(tag, 1, 0x00000000, 0x03ffffff);
1341 	}
1342 
1343 	bankn = 0;
1344 	val = pcicfgread(tag, MPC106_MEMEN);
1345 	for (n = 0; n < 4; n++) {
1346 		if ((val & (1U << n)) == 0)
1347 			break;
1348 		bankn = n;
1349 	}
1350 	bankn <<= 3;
1351 
1352 	val = pcicfgread(tag, MPC106_EXTMEMENDADDR1);
1353 	end =  ((val >> bankn) & 0x03) << 28;
1354 	val = pcicfgread(tag, MPC106_MEMENDADDR1);
1355 	end |= ((val >> bankn) & 0xff) << 20;
1356 	end |= 0xfffff;
1357 
1358 	return (end + 1); /* assume the end address matches total amount */
1359 }
1360 
1361 struct fis_dir_entry {
1362 	char		name[16];
1363 	uint32_t	startaddr;
1364 	uint32_t	loadaddr;
1365 	uint32_t	flashsize;
1366 	uint32_t	entryaddr;
1367 	uint32_t	filesize;
1368 	char		pad[256 - (16 + 5 * sizeof(uint32_t))];
1369 };
1370 
1371 #define FIS_LOWER_LIMIT	0xfff00000
1372 
1373 /*
1374  * Look for a Redboot-style Flash Image System FIS-directory and
1375  * return a pointer to the start address of the requested file.
1376  */
1377 static void *
redboot_fis_lookup(const char * filename)1378 redboot_fis_lookup(const char *filename)
1379 {
1380 	static const char FISdirname[16] = {
1381 	    'F', 'I', 'S', ' ',
1382 	    'd', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 0, 0, 0
1383 	};
1384 	struct fis_dir_entry *dir;
1385 
1386 	/*
1387 	 * The FIS directory is usually in the last sector of the flash.
1388 	 * But we do not know the sector size (erase size), so start
1389 	 * at 0xffffff00 and scan backwards in steps of the FIS directory
1390 	 * entry size (0x100).
1391 	 */
1392 	for (dir = (struct fis_dir_entry *)0xffffff00;
1393 	    (uint32_t)dir >= FIS_LOWER_LIMIT; dir--)
1394 		if (memcmp(dir->name, FISdirname, sizeof(FISdirname)) == 0)
1395 			break;
1396 	if ((uint32_t)dir < FIS_LOWER_LIMIT) {
1397 		printf("No FIS directory found!\n");
1398 		return NULL;
1399 	}
1400 
1401 	/* Now find filename by scanning the directory from beginning. */
1402 	dir = (struct fis_dir_entry *)dir->startaddr;
1403 	while (dir->name[0] != 0xff && (uint32_t)dir < 0xffffff00) {
1404 		if (strcmp(dir->name, filename) == 0)
1405 			return (void *)dir->startaddr;	/* found */
1406 		dir++;
1407 	}
1408 	printf("\"%s\" not found in FIS directory!\n", filename);
1409 	return NULL;
1410 }
1411 
1412 static void
read_mac_string(uint8_t * mac,char * p)1413 read_mac_string(uint8_t *mac, char *p)
1414 {
1415 	int i;
1416 
1417 	for (i = 0; i < 6; i++, p += 3)
1418 		*mac++ = read_hex(p);
1419 }
1420 
1421 /*
1422  * Scan through the Flash memory and look for a string starting at 512 bytes
1423  * block boundaries, matching the format: xx:xx:xx:xx:xx:xx<NUL>, where "x"
1424  * are hexadecimal digits.
1425  * Read the first match as our MAC address.
1426  * The start address of the search, p, *must* be dividable by 512!
1427  * Return false when no suitable MAC string was found.
1428  */
1429 static int
find_mac_string(uint8_t * mac,char * p)1430 find_mac_string(uint8_t *mac, char *p)
1431 {
1432 	int i;
1433 
1434 	for (;;) {
1435 		for (i = 0; i < 3 * 6; i += 3) {
1436 			if (!isxdigit((unsigned)p[i]) ||
1437 			    !isxdigit((unsigned)p[i + 1]))
1438 				break;
1439 			if ((i < 5 && p[i + 2] != ':') ||
1440 			    (i >= 5 && p[i + 2] != '\0'))
1441 				break;
1442 		}
1443 		if (i >= 6) {
1444 			/* found a valid MAC address */
1445 			read_mac_string(mac, p);
1446 			return 1;
1447 		}
1448 		if (p >= (char *)0xfffffe00)
1449 			break;
1450 		p += 0x200;
1451 	}
1452 	return 0;
1453 }
1454 
1455 
1456 /*
1457  * For cost saving reasons some NAS boxes lack SEEPROM for NIC's
1458  * ethernet address and keep it in their Flash memory instead.
1459  */
1460 void
read_mac_from_flash(uint8_t * mac)1461 read_mac_from_flash(uint8_t *mac)
1462 {
1463 	uint8_t *p;
1464 
1465 	switch (brdtype) {
1466 	case BRD_SYNOLOGY:
1467 		p = redboot_fis_lookup("vendor");
1468 		if (p == NULL)
1469 			break;
1470 		memcpy(mac, p, 6);
1471 		return;
1472 	case BRD_DLINKDSM:
1473 		read_mac_string(mac, (char *)0xfff0ff80);
1474 		return;
1475 	case BRD_QNAPTS:
1476 		if (find_mac_string(mac, (char *)0xfff00000))
1477 			return;
1478 		break;
1479 	default:
1480 		printf("Warning: This board has no known method defined "
1481 		    "to determine its MAC address!\n");
1482 		break;
1483 	}
1484 
1485 	/* set to 00:00:00:00:00:00 in case of error */
1486 	memset(mac, 0, 6);
1487 }
1488 
1489 #ifdef DEBUG
1490 void
sat_write(char * p,int len)1491 sat_write(char *p, int len)
1492 {
1493 	unsigned savedbase;
1494 
1495 	savedbase = uart1base;
1496 	uart1base = uart2base;
1497 	while (len--)
1498 		putchar(*p++);
1499 	uart1base = savedbase;
1500 }
1501 
1502 int
sat_getch(void)1503 sat_getch(void)
1504 {
1505 	unsigned lsr;
1506 
1507 	do {
1508 		lsr = UART_READ(uart2base, LSR);
1509 	} while ((lsr & LSR_DRDY) == 0);
1510 	return UART_READ(uart2base, RBR);
1511 }
1512 
1513 int
sat_tstch(void)1514 sat_tstch(void)
1515 {
1516 
1517 	return (UART_READ(uart2base, LSR) & LSR_DRDY) != 0;
1518 }
1519 #endif /* DEBUG */
1520