xref: /openbsd/sys/arch/alpha/mcbus/mcbus.c (revision 6aef9a4e)
1*6aef9a4eSmpi /* $OpenBSD: mcbus.c,v 1.5 2022/03/13 08:04:13 mpi Exp $ */
22f4de8e4Srobert /* $NetBSD: mcbus.c,v 1.19 2007/03/04 05:59:11 christos Exp $ */
32f4de8e4Srobert 
42f4de8e4Srobert /*
52f4de8e4Srobert  * Copyright (c) 1998 by Matthew Jacob
62f4de8e4Srobert  * NASA AMES Research Center.
72f4de8e4Srobert  * All rights reserved.
82f4de8e4Srobert  *
92f4de8e4Srobert  * Redistribution and use in source and binary forms, with or without
102f4de8e4Srobert  * modification, are permitted provided that the following conditions
112f4de8e4Srobert  * are met:
122f4de8e4Srobert  * 1. Redistributions of source code must retain the above copyright
132f4de8e4Srobert  *    notice immediately at the beginning of the file, without modification,
142f4de8e4Srobert  *    this list of conditions, and the following disclaimer.
152f4de8e4Srobert  * 2. Redistributions in binary form must reproduce the above copyright
162f4de8e4Srobert  *    notice, this list of conditions and the following disclaimer in the
172f4de8e4Srobert  *    documentation and/or other materials provided with the distribution.
182f4de8e4Srobert  * 3. The name of the author may not be used to endorse or promote products
192f4de8e4Srobert  *    derived from this software without specific prior written permission.
202f4de8e4Srobert  *
212f4de8e4Srobert  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
222f4de8e4Srobert  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
232f4de8e4Srobert  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
242f4de8e4Srobert  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
252f4de8e4Srobert  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
262f4de8e4Srobert  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
272f4de8e4Srobert  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
282f4de8e4Srobert  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
292f4de8e4Srobert  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
302f4de8e4Srobert  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
312f4de8e4Srobert  * SUCH DAMAGE.
322f4de8e4Srobert  */
332f4de8e4Srobert 
342f4de8e4Srobert /*
352f4de8e4Srobert  * Autoconfiguration routines for the MCBUS system
362f4de8e4Srobert  * bus found on AlphaServer 4100 systems.
372f4de8e4Srobert  */
382f4de8e4Srobert 
392f4de8e4Srobert #include <sys/param.h>
402f4de8e4Srobert #include <sys/systm.h>
412f4de8e4Srobert #include <sys/device.h>
422f4de8e4Srobert #include <sys/malloc.h>
432f4de8e4Srobert 
442f4de8e4Srobert #include <machine/autoconf.h>
452f4de8e4Srobert #include <machine/rpb.h>
462f4de8e4Srobert #include <machine/pte.h>
472f4de8e4Srobert 
482f4de8e4Srobert #include <alpha/mcbus/mcbusreg.h>
492f4de8e4Srobert #include <alpha/mcbus/mcbusvar.h>
502f4de8e4Srobert 
512f4de8e4Srobert #include <alpha/pci/mcpciareg.h>
522f4de8e4Srobert 
532f4de8e4Srobert #define KV(_addr)	((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
542f4de8e4Srobert #define	MCPCIA_EXISTS(mid, gid)	\
552f4de8e4Srobert 	(!badaddr((void *)KV(MCPCIA_BRIDGE_ADDR(gid, mid)), sizeof (u_int32_t)))
562f4de8e4Srobert 
572f4de8e4Srobert struct mcbus_cpu_busdep mcbus_primary;
582f4de8e4Srobert 
592f4de8e4Srobert int	mcbusmatch (struct device *, void *, void *);
602f4de8e4Srobert void	mcbusattach (struct device *, struct device *, void *);
612f4de8e4Srobert int	mcbusprint (void *, const char *);
622f4de8e4Srobert int	mcbussbm (struct device *, void *, void *);
632f4de8e4Srobert 
642f4de8e4Srobert const	char *mcbus_node_type_str (u_int8_t);
652f4de8e4Srobert 
662f4de8e4Srobert typedef struct {
672f4de8e4Srobert 	struct device	mcbus_dev;
682f4de8e4Srobert 	u_int8_t	mcbus_types[MCBUS_MID_MAX];
692f4de8e4Srobert } mcbus_softc_t;
702f4de8e4Srobert 
71*6aef9a4eSmpi const struct cfattach mcbus_ca = {
722f4de8e4Srobert 	sizeof(mcbus_softc_t), mcbusmatch, mcbusattach
732f4de8e4Srobert };
742f4de8e4Srobert 
752f4de8e4Srobert struct cfdriver mcbus_cd = {
762f4de8e4Srobert         NULL, "mcbus", DV_DULL,
772f4de8e4Srobert };
782f4de8e4Srobert 
792f4de8e4Srobert /*
802f4de8e4Srobert  * Tru64 UNIX (formerly Digital UNIX (formerly DEC OSF/1)) probes for MCPCIAs
812f4de8e4Srobert  * in the following order:
822f4de8e4Srobert  *
832f4de8e4Srobert  *	5, 4, 7, 6
842f4de8e4Srobert  *
852f4de8e4Srobert  * This is so that the built-in CD-ROM on the internal 53c810 is always
862f4de8e4Srobert  * dka500.  We probe them in the same order, for consistency.
872f4de8e4Srobert  */
882f4de8e4Srobert const int mcbus_mcpcia_probe_order[] = { 5, 4, 7, 6 };
892f4de8e4Srobert 
902f4de8e4Srobert extern void mcpcia_config_cleanup (void);
912f4de8e4Srobert 
922f4de8e4Srobert int
mcbusprint(aux,cp)932f4de8e4Srobert mcbusprint(aux, cp)
942f4de8e4Srobert 	void *aux;
952f4de8e4Srobert 	const char *cp;
962f4de8e4Srobert {
972f4de8e4Srobert 	struct mcbus_dev_attach_args *tap = aux;
982f4de8e4Srobert 	printf(" mid %d: %s", tap->ma_mid,
992f4de8e4Srobert 	    mcbus_node_type_str(tap->ma_type));
1002f4de8e4Srobert 	return (UNCONF);
1012f4de8e4Srobert }
1022f4de8e4Srobert 
1032f4de8e4Srobert int
mcbussbm(parent,cf,aux)1042f4de8e4Srobert mcbussbm(parent, cf, aux)
1052f4de8e4Srobert 	struct device *parent;
1062f4de8e4Srobert 	void *cf;
1072f4de8e4Srobert 	void *aux;
1082f4de8e4Srobert {
1092f4de8e4Srobert 	struct mcbus_dev_attach_args *tap = aux;
1102f4de8e4Srobert 	struct cfdata *mcf = (struct cfdata *)cf;
1112f4de8e4Srobert 
1122f4de8e4Srobert 	if (mcf->cf_loc[MCBUSCF_MID] != MCBUSCF_MID_DEFAULT &&
1132f4de8e4Srobert 	    mcf->cf_loc[MCBUSCF_MID] != tap->ma_mid)
1142f4de8e4Srobert 		return (0);
1152f4de8e4Srobert 
1162f4de8e4Srobert 
1172f4de8e4Srobert 	return ((*mcf->cf_attach->ca_match)(parent, mcf, aux));
1182f4de8e4Srobert }
1192f4de8e4Srobert 
1202f4de8e4Srobert int
mcbusmatch(parent,cf,aux)1212f4de8e4Srobert mcbusmatch(parent, cf, aux)
1222f4de8e4Srobert 	struct device *parent;
1232f4de8e4Srobert 	void *cf;
1242f4de8e4Srobert 	void *aux;
1252f4de8e4Srobert {
1262f4de8e4Srobert 	struct mainbus_attach_args *ma = aux;
1272f4de8e4Srobert 
1282f4de8e4Srobert 	/* Make sure we're looking for a MCBUS. */
1292f4de8e4Srobert 	if (strcmp(ma->ma_name, mcbus_cd.cd_name) != 0)
1302f4de8e4Srobert 		return (0);
1312f4de8e4Srobert 
1322f4de8e4Srobert 	/*
1332f4de8e4Srobert 	 * Only available on 4100 processor type platforms.
1342f4de8e4Srobert 	 */
1352f4de8e4Srobert 	if (cputype != ST_DEC_4100)
1362f4de8e4Srobert 		return (0);
1372f4de8e4Srobert 
1382f4de8e4Srobert 	return (1);
1392f4de8e4Srobert }
1402f4de8e4Srobert 
1412f4de8e4Srobert void
mcbusattach(parent,self,aux)1422f4de8e4Srobert mcbusattach(parent, self, aux)
1432f4de8e4Srobert 	struct device *parent;
1442f4de8e4Srobert 	struct device *self;
1452f4de8e4Srobert 	void *aux;
1462f4de8e4Srobert {
1472f4de8e4Srobert 	static const char *bcs[CPU_BCacheMask + 1] = {
1482f4de8e4Srobert 		"No", "1MB", "2MB", "4MB",
1492f4de8e4Srobert 	};
1502f4de8e4Srobert 	struct mcbus_dev_attach_args ta;
1512f4de8e4Srobert 	mcbus_softc_t *mbp = (mcbus_softc_t *)self;
1522f4de8e4Srobert 	int i, mid;
1532f4de8e4Srobert 
1542f4de8e4Srobert 	printf(": %s BCache\n", mcbus_primary.mcbus_valid ?
1552f4de8e4Srobert 	    bcs[mcbus_primary.mcbus_bcache] : "Unknown");
1562f4de8e4Srobert 
1572f4de8e4Srobert 	mbp->mcbus_types[0] = MCBUS_TYPE_RES;
1586a37c571Sjsg 	for (mid = 1; mid < MCBUS_MID_MAX; ++mid)
1592f4de8e4Srobert 		mbp->mcbus_types[mid] = MCBUS_TYPE_UNK;
1602f4de8e4Srobert 
1612f4de8e4Srobert 	/*
1622f4de8e4Srobert 	 * Find and "configure" memory.
1632f4de8e4Srobert 	 */
1642f4de8e4Srobert 	ta.ma_name = mcbus_cd.cd_name;
1652f4de8e4Srobert 	ta.ma_gid = MCBUS_GID_FROM_INSTANCE(0);
1662f4de8e4Srobert 	ta.ma_mid = 1;
1672f4de8e4Srobert 	ta.ma_type = MCBUS_TYPE_MEM;
1682f4de8e4Srobert 	mbp->mcbus_types[1] = MCBUS_TYPE_MEM;
1692f4de8e4Srobert 
1702f4de8e4Srobert 	(void) config_found_sm(self, &ta, mcbusprint, mcbussbm);
1712f4de8e4Srobert 
1722f4de8e4Srobert 	/*
1732f4de8e4Srobert 	 * Now find PCI busses.
1742f4de8e4Srobert 	 */
1752f4de8e4Srobert 	for (i = 0; i < MCPCIA_PER_MCBUS; i++) {
1762f4de8e4Srobert 		mid = mcbus_mcpcia_probe_order[i];
1772f4de8e4Srobert 		ta.ma_name = mcbus_cd.cd_name;
1782f4de8e4Srobert 		ta.ma_gid = MCBUS_GID_FROM_INSTANCE(0);
1792f4de8e4Srobert 		ta.ma_mid = mid;
1802f4de8e4Srobert 		ta.ma_type = MCBUS_TYPE_PCI;
1812f4de8e4Srobert 		if (MCPCIA_EXISTS(ta.ma_mid, ta.ma_gid))
1822f4de8e4Srobert 			(void) config_found_sm(self, &ta, mcbusprint,
1832f4de8e4Srobert 					mcbussbm);
1842f4de8e4Srobert 	}
1852f4de8e4Srobert 
1862f4de8e4Srobert 	mcpcia_config_cleanup();
1872f4de8e4Srobert }
1882f4de8e4Srobert 
1892f4de8e4Srobert const char *
mcbus_node_type_str(type)1902f4de8e4Srobert mcbus_node_type_str(type)
1912f4de8e4Srobert 	u_int8_t type;
1922f4de8e4Srobert {
1932f4de8e4Srobert 	switch (type) {
1942f4de8e4Srobert 	case MCBUS_TYPE_RES:
1952f4de8e4Srobert 		panic ("RESERVED TYPE IN MCBUS_NODE_TYPE_STR");
1962f4de8e4Srobert 		break;
1972f4de8e4Srobert 	case MCBUS_TYPE_UNK:
1982f4de8e4Srobert 		panic ("UNKNOWN TYPE IN MCBUS_NODE_TYPE_STR");
1992f4de8e4Srobert 		break;
2002f4de8e4Srobert 	case MCBUS_TYPE_MEM:
2012f4de8e4Srobert 		return ("Memory");
2022f4de8e4Srobert 	case MCBUS_TYPE_CPU:
2032f4de8e4Srobert 		return ("CPU");
2042f4de8e4Srobert 	case MCBUS_TYPE_PCI:
2052f4de8e4Srobert 		return ("PCI Bridge");
2062f4de8e4Srobert 	default:
20736fd90dcSjsg 		panic("REALLY UNKNOWN (%x) TYPE IN MCBUS_NODE_TYPE_STR", type);
2082f4de8e4Srobert 		break;
2092f4de8e4Srobert 	}
2102f4de8e4Srobert }
211