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