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