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