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