xref: /netbsd-src/sys/arch/alpha/mcbus/mcbus.c (revision 4e7cd6980945784a5920db424192dc10d2f6a15a)
1*4e7cd698Smsaitoh /* $NetBSD: mcbus.c,v 1.26 2023/06/19 08:40:29 msaitoh Exp $ */
24fa71d82Smjacob 
34fa71d82Smjacob /*
44fa71d82Smjacob  * Copyright (c) 1998 by Matthew Jacob
54fa71d82Smjacob  * NASA AMES Research Center.
64fa71d82Smjacob  * All rights reserved.
74fa71d82Smjacob  *
84fa71d82Smjacob  * Redistribution and use in source and binary forms, with or without
94fa71d82Smjacob  * modification, are permitted provided that the following conditions
104fa71d82Smjacob  * are met:
114fa71d82Smjacob  * 1. Redistributions of source code must retain the above copyright
124fa71d82Smjacob  *    notice immediately at the beginning of the file, without modification,
134fa71d82Smjacob  *    this list of conditions, and the following disclaimer.
144fa71d82Smjacob  * 2. Redistributions in binary form must reproduce the above copyright
154fa71d82Smjacob  *    notice, this list of conditions and the following disclaimer in the
164fa71d82Smjacob  *    documentation and/or other materials provided with the distribution.
174fa71d82Smjacob  * 3. The name of the author may not be used to endorse or promote products
184fa71d82Smjacob  *    derived from this software without specific prior written permission.
194fa71d82Smjacob  *
204fa71d82Smjacob  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
214fa71d82Smjacob  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
224fa71d82Smjacob  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
234fa71d82Smjacob  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
244fa71d82Smjacob  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
254fa71d82Smjacob  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
264fa71d82Smjacob  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
274fa71d82Smjacob  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
284fa71d82Smjacob  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
294fa71d82Smjacob  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
304fa71d82Smjacob  * SUCH DAMAGE.
314fa71d82Smjacob  */
324fa71d82Smjacob 
334fa71d82Smjacob /*
3470e72d55Smjacob  * Autoconfiguration routines for the MCBUS system
3570e72d55Smjacob  * bus found on AlphaServer 4100 systems.
364fa71d82Smjacob  */
374fa71d82Smjacob 
384fa71d82Smjacob #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
394fa71d82Smjacob 
40*4e7cd698Smsaitoh __KERNEL_RCSID(0, "$NetBSD: mcbus.c,v 1.26 2023/06/19 08:40:29 msaitoh Exp $");
414fa71d82Smjacob 
424fa71d82Smjacob #include <sys/param.h>
434fa71d82Smjacob #include <sys/systm.h>
444fa71d82Smjacob #include <sys/device.h>
454fa71d82Smjacob 
464fa71d82Smjacob #include <machine/autoconf.h>
474fa71d82Smjacob #include <machine/rpb.h>
484fa71d82Smjacob #include <machine/pte.h>
494fa71d82Smjacob 
504fa71d82Smjacob #include <alpha/mcbus/mcbusreg.h>
514fa71d82Smjacob #include <alpha/mcbus/mcbusvar.h>
524fa71d82Smjacob 
5352911422Sthorpej #include <alpha/pci/mcpciareg.h>
5452911422Sthorpej 
554fa71d82Smjacob #include "locators.h"
564fa71d82Smjacob 
5753524e44Schristos #define KV(_addr)	((void *)ALPHA_PHYS_TO_K0SEG((_addr)))
588cf9a148Smjacob #define	MCPCIA_EXISTS(mid, gid)	\
59eacc5f97Smatt 	(!badaddr((void *)KV(MCPCIA_BRIDGE_ADDR(gid, mid)), sizeof (uint32_t)))
604fa71d82Smjacob 
614fa71d82Smjacob extern struct cfdriver mcbus_cd;
624fa71d82Smjacob 
634fa71d82Smjacob struct mcbus_cpu_busdep mcbus_primary;
644fa71d82Smjacob 
653f4a1f5aSjoerg static int	mcbusmatch(device_t, cfdata_t, void *);
663f4a1f5aSjoerg static void	mcbusattach(device_t, device_t, void *);
673f4a1f5aSjoerg static int	mcbusprint(void *, const char *);
68eacc5f97Smatt static const char *mcbus_node_type_str(uint8_t);
694fa71d82Smjacob 
704fa71d82Smjacob typedef struct {
71eacc5f97Smatt 	uint8_t	mcbus_types[MCBUS_MID_MAX];
724fa71d82Smjacob } mcbus_softc_t;
734fa71d82Smjacob 
743f4a1f5aSjoerg CFATTACH_DECL_NEW(mcbus, sizeof (mcbus_softc_t),
75b96bc0d7Sthorpej     mcbusmatch, mcbusattach, NULL, NULL);
764fa71d82Smjacob 
779af474a6Sthorpej /*
789af474a6Sthorpej  * Tru64 UNIX (formerly Digital UNIX (formerly DEC OSF/1)) probes for MCPCIAs
799af474a6Sthorpej  * in the following order:
809af474a6Sthorpej  *
819af474a6Sthorpej  *	5, 4, 7, 6
829af474a6Sthorpej  *
839af474a6Sthorpej  * This is so that the built-in CD-ROM on the internal 53c810 is always
849af474a6Sthorpej  * dka500.  We probe them in the same order, for consistency.
859af474a6Sthorpej  */
869af474a6Sthorpej const int mcbus_mcpcia_probe_order[] = { 5, 4, 7, 6 };
874fa71d82Smjacob 
883f4a1f5aSjoerg extern void mcpcia_config_cleanup(void);
894fa71d82Smjacob 
904fa71d82Smjacob static int
mcbusprint(void * aux,const char * cp)913f4a1f5aSjoerg mcbusprint(void *aux, const char *cp)
924fa71d82Smjacob {
934fa71d82Smjacob 	struct mcbus_dev_attach_args *tap = aux;
947ca7bdb3Sthorpej 	aprint_normal(" mid %d: %s", tap->ma_mid,
957ca7bdb3Sthorpej 	    mcbus_node_type_str(tap->ma_type));
964fa71d82Smjacob 	return (UNCONF);
974fa71d82Smjacob }
984fa71d82Smjacob 
994fa71d82Smjacob static int
mcbusmatch(device_t parent,cfdata_t cf,void * aux)1003f4a1f5aSjoerg mcbusmatch(device_t parent, cfdata_t cf, void *aux)
1014fa71d82Smjacob {
102d19fbe11Sthorpej 	struct mainbus_attach_args *ma = aux;
1034fa71d82Smjacob 
1044fa71d82Smjacob 	/* Make sure we're looking for a MCBUS. */
105d19fbe11Sthorpej 	if (strcmp(ma->ma_name, mcbus_cd.cd_name) != 0)
1064fa71d82Smjacob 		return (0);
1074fa71d82Smjacob 
1084fa71d82Smjacob 	/*
1094fa71d82Smjacob 	 * Only available on 4100 processor type platforms.
1104fa71d82Smjacob 	 */
1114fa71d82Smjacob 	if (cputype != ST_DEC_4100)
1124fa71d82Smjacob 		return (0);
1134fa71d82Smjacob 	return (1);
1144fa71d82Smjacob }
1154fa71d82Smjacob 
1164fa71d82Smjacob static void
mcbusattach(device_t parent,device_t self,void * aux)1173f4a1f5aSjoerg mcbusattach(device_t parent, device_t self, void *aux)
1184fa71d82Smjacob {
11988b07008Sthorpej 	static const char * const bcs[CPU_BCacheMask + 1] = {
12052911422Sthorpej 		"No", "1MB", "2MB", "4MB",
1214fa71d82Smjacob 	};
1224fa71d82Smjacob 	struct mcbus_dev_attach_args ta;
1233f4a1f5aSjoerg 	mcbus_softc_t *mbp = device_private(self);
1249af474a6Sthorpej 	int i, mid;
125fa3cb84dSdrochner 	int locs[MCBUSCF_NLOCS];
1264fa71d82Smjacob 
12752911422Sthorpej 	printf(": %s BCache\n", mcbus_primary.mcbus_valid ?
12852911422Sthorpej 	    bcs[mcbus_primary.mcbus_bcache] : "Unknown");
1294fa71d82Smjacob 
1304fa71d82Smjacob 	mbp->mcbus_types[0] = MCBUS_TYPE_RES;
131cf2b1d22Schs 	for (mid = 1; mid < MCBUS_MID_MAX; ++mid)
1324fa71d82Smjacob 		mbp->mcbus_types[mid] = MCBUS_TYPE_UNK;
1334fa71d82Smjacob 
1344fa71d82Smjacob 	/*
1354fa71d82Smjacob 	 * Find and "configure" memory.
1364fa71d82Smjacob 	 */
13752911422Sthorpej 
1389af474a6Sthorpej 	/*
1399af474a6Sthorpej 	 * XXX If we ever support more than one MCBUS, we'll
1409af474a6Sthorpej 	 * XXX have to probe for them, and map them to unit
1419af474a6Sthorpej 	 * XXX numbers.
1429af474a6Sthorpej 	 */
1439af474a6Sthorpej 	ta.ma_gid = MCBUS_GID_FROM_INSTANCE(0);
1444fa71d82Smjacob 	ta.ma_mid = 1;
1454fa71d82Smjacob 	ta.ma_type = MCBUS_TYPE_MEM;
1464fa71d82Smjacob 	mbp->mcbus_types[1] = MCBUS_TYPE_MEM;
147fa3cb84dSdrochner 	locs[MCBUSCF_MID] = 1;
1482685996bSthorpej 	config_found(self, &ta, mcbusprint,
149c7fb772bSthorpej 	    CFARGS(.submatch = config_stdsubmatch,
150c7fb772bSthorpej 		   .locators = locs));
1514fa71d82Smjacob 
1524fa71d82Smjacob 	/*
1539af474a6Sthorpej 	 * Now find PCI busses.
1544fa71d82Smjacob 	 */
1554fa71d82Smjacob 	for (i = 0; i < MCPCIA_PER_MCBUS; i++) {
1569af474a6Sthorpej 		mid = mcbus_mcpcia_probe_order[i];
1579af474a6Sthorpej 		/*
1589af474a6Sthorpej 		 * XXX If we ever support more than one MCBUS, we'll
1599af474a6Sthorpej 		 * XXX have to probe for them, and map them to unit
1609af474a6Sthorpej 		 * XXX numbers.
1619af474a6Sthorpej 		 */
1629af474a6Sthorpej 		ta.ma_gid = MCBUS_GID_FROM_INSTANCE(0);
1634fa71d82Smjacob 		ta.ma_mid = mid;
1644fa71d82Smjacob 		ta.ma_type = MCBUS_TYPE_PCI;
165fa3cb84dSdrochner 		locs[MCBUSCF_MID] = mid;
16652911422Sthorpej 		if (MCPCIA_EXISTS(ta.ma_mid, ta.ma_gid))
1672685996bSthorpej 			config_found(self, &ta, mcbusprint,
168c7fb772bSthorpej 			    CFARGS(.submatch = config_stdsubmatch,
169c7fb772bSthorpej 				   .locators = locs));
1708cf9a148Smjacob 	}
1714fa71d82Smjacob 
17252911422Sthorpej #if 0
1734fa71d82Smjacob 	/*
1744fa71d82Smjacob 	 * Deal with hooking CPU instances to MCBUS module ids.
1754fa71d82Smjacob 	 *
1764fa71d82Smjacob 	 * Note that we do this here because it's the read of
1774fa71d82Smjacob 	 * stupid MCPCIA WHOAMI register that can get us the
1784fa71d82Smjacob 	 * module ID and type of the configuring CPU.
1794fa71d82Smjacob 	 */
1804fa71d82Smjacob 
1814fa71d82Smjacob 	if (mcbus_primary.mcbus_valid) {
1824fa71d82Smjacob 		mid = mcbus_primary.mcbus_cpu_mid;
1833f4a1f5aSjoerg 		printf("%s mid %d: %s %s\n", device_xname(self),
1844fa71d82Smjacob 		    mid, mcbus_node_type_str(MCBUS_TYPE_CPU),
18573c269feSmjacob 		    bcs[mcbus_primary.mcbus_bcache & 0x7]);
1869af474a6Sthorpej 		/*
1879af474a6Sthorpej 		 * XXX If we ever support more than one MCBUS, we'll
1889af474a6Sthorpej 		 * XXX have to probe for them, and map them to unit
1899af474a6Sthorpej 		 * XXX numbers.
1909af474a6Sthorpej 		 */
1919af474a6Sthorpej 		ta.ma_gid = MCBUS_GID_FROM_INSTANCE(0);
1924fa71d82Smjacob 		ta.ma_mid = mid;
1934fa71d82Smjacob 		ta.ma_type = MCBUS_TYPE_CPU;
1944fa71d82Smjacob 		mbp->mcbus_types[mid] = MCBUS_TYPE_CPU;
195fa3cb84dSdrochner 		locs[MCBUSCF_MID] = mid;
1962685996bSthorpej 		config_found(self, &ta, mcbusprint,
197c7fb772bSthorpej 		    CFARGS(.submatch = config_stdsubmatch,
198c7fb772bSthorpej 			   .locators = locs));
1994fa71d82Smjacob 	}
20052911422Sthorpej #endif
2014fa71d82Smjacob 
2024fa71d82Smjacob 	/*
2034fa71d82Smjacob 	 * Now clean up after configuring everything.
2044fa71d82Smjacob 	 *
2054fa71d82Smjacob 	 * This is an unfortunate layering violation- but
2064fa71d82Smjacob 	 * we can't enable interrupts until *all* probing
2074fa71d82Smjacob 	 * is done, but the code and knowledge to clean
2084fa71d82Smjacob 	 * up after probing and to enable interrupts is
2094fa71d82Smjacob 	 * down in the MCPCIA layer.
2104fa71d82Smjacob 	 */
2114fa71d82Smjacob 	mcpcia_config_cleanup();
2124fa71d82Smjacob }
2134fa71d82Smjacob 
21494a3347aSdrochner static const char *
mcbus_node_type_str(uint8_t type)215eacc5f97Smatt mcbus_node_type_str(uint8_t type)
2164fa71d82Smjacob {
2174fa71d82Smjacob 	switch (type) {
2184fa71d82Smjacob 	case MCBUS_TYPE_RES:
2194fa71d82Smjacob 		panic ("RESERVED TYPE IN MCBUS_NODE_TYPE_STR");
2204fa71d82Smjacob 		break;
2214fa71d82Smjacob 	case MCBUS_TYPE_UNK:
2224fa71d82Smjacob 		panic ("UNKNOWN TYPE IN MCBUS_NODE_TYPE_STR");
2234fa71d82Smjacob 		break;
2244fa71d82Smjacob 	case MCBUS_TYPE_MEM:
2254fa71d82Smjacob 		return ("Memory");
2264fa71d82Smjacob 	case MCBUS_TYPE_CPU:
2274fa71d82Smjacob 		return ("CPU");
2284fa71d82Smjacob 	case MCBUS_TYPE_PCI:
2294fa71d82Smjacob 		return ("PCI Bridge");
2304fa71d82Smjacob 	default:
231*4e7cd698Smsaitoh 		panic("REALLY UNKNOWN (%x) TYPE IN MCBUS_NODE_TYPE_STR", type);
2324fa71d82Smjacob 		break;
2334fa71d82Smjacob 	}
2344fa71d82Smjacob }
235