dec_6600.c revision 1.40
11.40Sthorpej/* $NetBSD: dec_6600.c,v 1.40 2025/10/03 14:12:03 thorpej Exp $ */
21.1Sross
31.1Sross/*
41.1Sross * Copyright (c) 1995, 1996, 1997 Carnegie-Mellon University.
51.1Sross * All rights reserved.
61.1Sross *
71.1Sross * Author: Chris G. Demetriou
81.33Smatt *
91.1Sross * Permission to use, copy, modify and distribute this software and
101.1Sross * its documentation is hereby granted, provided that both the copyright
111.1Sross * notice and this permission notice appear in all copies of the
121.1Sross * software, derivative works or modified versions, and any portions
131.1Sross * thereof, and that both notices appear in supporting documentation.
141.33Smatt *
151.33Smatt * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
161.33Smatt * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
171.1Sross * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
181.33Smatt *
191.1Sross * Carnegie Mellon requests users of this software to return to
201.1Sross *
211.1Sross *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
221.1Sross *  School of Computer Science
231.1Sross *  Carnegie Mellon University
241.1Sross *  Pittsburgh PA 15213-3890
251.1Sross *
261.1Sross * any improvements or extensions that they make and grant Carnegie the
271.1Sross * rights to redistribute these changes.
281.1Sross */
291.1Sross
301.1Sross#include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
311.1Sross
321.40Sthorpej__KERNEL_RCSID(0, "$NetBSD: dec_6600.c,v 1.40 2025/10/03 14:12:03 thorpej Exp $");
331.1Sross
341.1Sross#include <sys/param.h>
351.1Sross#include <sys/systm.h>
361.1Sross#include <sys/device.h>
371.35Sthorpej#include <sys/lwp.h>
381.1Sross
391.1Sross#include <machine/rpb.h>
401.1Sross#include <machine/autoconf.h>
411.14Sgehenna#include <machine/cpuconf.h>
421.30Shans#include <machine/alpha.h>
431.30Shans#include <machine/logout.h>
441.1Sross
451.1Sross#include <dev/pci/pcivar.h>
461.1Sross
471.1Sross#include <alpha/pci/tsreg.h>
481.1Sross#include <alpha/pci/tsvar.h>
491.1Sross
501.1Sross#define	DR_VERBOSE(f) while (0)
511.1Sross
521.27Sdslvoid dec_6600_init(void);
531.27Sdslstatic void dec_6600_cons_init(void);
541.31Smattstatic void dec_6600_device_register(device_t, void *);
551.30Shansstatic void dec_6600_mcheck(unsigned long, struct ev6_logout_area *);
561.30Shansstatic void dec_6600_mcheck_sys(unsigned int, struct ev6_logout_area *);
571.30Shansstatic void dec_6600_mcheck_handler(unsigned long, struct trapframe *,
581.30Shans				    unsigned long, unsigned long);
591.1Sross
601.38Sthorpejstatic const struct alpha_variation_table dec_6600_variations[] = {
611.38Sthorpej	{ SV_ST_DP264, "AlphaPC DP264" },
621.38Sthorpej	{ SV_ST_CLIPPER, "AlphaServer ES40 (\"Clipper\")" },
631.38Sthorpej	{ SV_ST_GOLDRUSH, "AlphaServer DS20 (\"GoldRush\")" },
641.38Sthorpej	{ SV_ST_WEBBRICK, "AlphaServer DS10 (\"WebBrick\")" },
651.38Sthorpej	{ SV_ST_SHARK, "AlphaServer DS20L (\"Shark\")" },
661.38Sthorpej	{ 0, NULL },
671.38Sthorpej};
681.38Sthorpej
691.38Sthorpejstatic const struct alpha_variation_table dec_titan_variations[] = {
701.38Sthorpej	{ 0, NULL },
711.38Sthorpej};
721.38Sthorpej
731.1Srossvoid
741.33Smattdec_6600_init(void)
751.1Sross{
761.38Sthorpej	uint64_t variation;
771.1Sross
781.38Sthorpej	platform.family = (hwrpb->rpb_type == ST_DEC_TITAN) ? "Titan"
791.38Sthorpej							    : "6600";
801.1Sross
811.1Sross	if ((platform.model = alpha_dsr_sysname()) == NULL) {
821.38Sthorpej		const struct alpha_variation_table *vartab =
831.38Sthorpej		    (hwrpb->rpb_type == ST_DEC_TITAN) ? dec_titan_variations
841.38Sthorpej						      : dec_6600_variations;
851.38Sthorpej		variation = hwrpb->rpb_variation & SV_ST_MASK;
861.38Sthorpej		if ((platform.model = alpha_variation_name(variation,
871.38Sthorpej							   vartab)) == NULL) {
881.38Sthorpej			platform.model = alpha_unknown_sysname();
891.38Sthorpej		}
901.1Sross	}
911.1Sross
921.1Sross	platform.iobus = "tsc";
931.1Sross	platform.cons_init = dec_6600_cons_init;
941.1Sross	platform.device_register = dec_6600_device_register;
951.30Shans	platform.mcheck_handler = dec_6600_mcheck_handler;
961.30Shans
971.30Shans	/* enable Cchip and Pchip error interrupts */
981.30Shans	STQP(TS_C_DIM0) = 0xe000000000000000;
991.30Shans	STQP(TS_C_DIM1) = 0xe000000000000000;
1001.1Sross}
1011.1Sross
1021.1Srossstatic void
1031.33Smattdec_6600_cons_init(void)
1041.1Sross{
1051.1Sross	struct ctb *ctb;
1061.33Smatt	uint64_t ctbslot;
1071.1Sross	struct tsp_config *tsp;
1081.39Sthorpej	bus_space_tag_t isa_iot, isa_memt;
1091.1Sross
1101.26Syamt	ctb = (struct ctb *)(((char *)hwrpb) + hwrpb->rpb_ctb_off);
1111.1Sross	ctbslot = ctb->ctb_turboslot;
1121.1Sross
1131.8Sthorpej	/* Console hose defaults to hose 0. */
1141.8Sthorpej	tsp_console_hose = 0;
1151.8Sthorpej
1161.36Sthorpej	tsp = tsp_init(tsp_console_hose);
1171.1Sross
1181.39Sthorpej	isa_iot = &tsp->pc_iot;
1191.39Sthorpej	isa_memt = &tsp->pc_memt;
1201.39Sthorpej
1211.1Sross	switch (ctb->ctb_term_type) {
1221.33Smatt	case CTB_PRINTERPORT:
1231.1Sross		/* serial console ... */
1241.1Sross		assert(CTB_TURBOSLOT_HOSE(ctbslot) == 0);
1251.39Sthorpej		break;
1261.1Sross
1271.12Sthorpej	case CTB_GRAPHICS:
1281.39Sthorpej		/* PCI display might be on a different hose. */
1291.39Sthorpej		if (CTB_TURBOSLOT_TYPE(ctbslot) != CTB_TURBOSLOT_TYPE_ISA) {
1301.8Sthorpej			tsp_console_hose = CTB_TURBOSLOT_HOSE(ctbslot);
1311.36Sthorpej			tsp = tsp_init(tsp_console_hose);
1321.1Sross		}
1331.1Sross		break;
1341.1Sross
1351.1Sross	default:
1361.39Sthorpej		/* Let pci_consinit() handle it. */
1371.39Sthorpej		break;
1381.39Sthorpej	}
1391.1Sross
1401.39Sthorpej	pci_consinit(&tsp->pc_pc, &tsp->pc_iot, &tsp->pc_memt,
1411.39Sthorpej	    isa_iot, isa_memt);
1421.1Sross}
1431.1Sross
1441.1Srossstatic void
1451.31Smattdec_6600_device_register(device_t dev, void *aux)
1461.1Sross{
1471.39Sthorpej	static device_t primarydev;
1481.1Sross	struct bootdev_data *b = bootdev_data;
1491.31Smatt	device_t parent = device_parent(dev);
1501.1Sross
1511.38Sthorpej	/*
1521.38Sthorpej	 * First section: Deal with system-specific quirks.
1531.38Sthorpej	 */
1541.38Sthorpej
1551.38Sthorpej	if ((hwrpb->rpb_variation & SV_ST_MASK) == SV_ST_WEBBRICK) {
1561.38Sthorpej		/*
1571.38Sthorpej		 * DMA on the on-board ALI IDE controller is not
1581.38Sthorpej		 * working correctly; disable it for now to let
1591.38Sthorpej		 * the systems at least hobble along.
1601.38Sthorpej		 *
1611.38Sthorpej		 * N.B. There's only one Pchip on a DS10, do there
1621.38Sthorpej		 * is not need to determine which hose we have here.
1631.38Sthorpej		 *
1641.38Sthorpej		 * XXX This is meant to be temporary until we can find
1651.38Sthorpej		 * XXX and fix the issue with bus-master DMA.
1661.38Sthorpej		 */
1671.38Sthorpej		if (device_is_a(parent, "pci") && device_is_a(dev, "aceride")) {
1681.38Sthorpej			struct pci_attach_args *pa = aux;
1691.38Sthorpej
1701.38Sthorpej			if (pa->pa_bus == 0 && pa->pa_device == 13 &&
1711.38Sthorpej			    pa->pa_function == 0) {
1721.40Sthorpej				device_setprop_bool(dev,
1731.38Sthorpej				    "pciide-disable-dma", true);
1741.38Sthorpej			}
1751.38Sthorpej		}
1761.38Sthorpej	}
1771.38Sthorpej
1781.38Sthorpej	/*
1791.38Sthorpej	 * Second section: Boot device detection.
1801.38Sthorpej	 */
1811.38Sthorpej
1821.39Sthorpej	if (booted_device != NULL || b == NULL) {
1831.1Sross		return;
1841.1Sross	}
1851.21Smycroft
1861.1Sross	if (primarydev == NULL) {
1871.39Sthorpej		if (device_is_a(dev, "tsp")) {
1881.1Sross			struct tsp_attach_args *tsp = aux;
1891.1Sross
1901.39Sthorpej			if (b->bus == tsp->tsp_slot) {
1911.39Sthorpej				primarydev = dev;
1921.39Sthorpej				DR_VERBOSE(printf("\nprimarydev = %s\n",
1931.31Smatt				    device_xname(dev)));
1941.21Smycroft			}
1951.1Sross		}
1961.21Smycroft		return;
1971.29Smhitch	}
1981.29Smhitch
1991.39Sthorpej	pci_find_bootdev(primarydev, dev, aux);
2001.1Sross}
2011.30Shans
2021.30Shansstatic void
2031.30Shansdec_6600_mcheck(unsigned long vector, struct ev6_logout_area *la)
2041.30Shans{
2051.30Shans	const char *t = "Unknown", *c = "";
2061.30Shans
2071.30Shans	if (vector == ALPHA_SYS_ERROR || vector == ALPHA_PROC_ERROR)
2081.30Shans		c = " Correctable";
2091.30Shans
2101.30Shans	switch (vector) {
2111.30Shans	case ALPHA_SYS_ERROR:
2121.30Shans	case ALPHA_SYS_MCHECK:
2131.30Shans		t = "System";
2141.30Shans		break;
2151.30Shans
2161.30Shans	case ALPHA_PROC_ERROR:
2171.30Shans	case ALPHA_PROC_MCHECK:
2181.30Shans		t = "Processor";
2191.30Shans		break;
2201.30Shans
2211.30Shans	case ALPHA_ENV_MCHECK:
2221.30Shans		t = "Environmental";
2231.30Shans		break;
2241.30Shans	}
2251.30Shans
2261.30Shans	printf("\n%s%s Machine Check (%lx): "
2271.30Shans	       "Rev 0x%x, Code 0x%x, Flags 0x%x\n\n",
2281.30Shans	       t, c, vector, la->mchk_rev, la->mchk_code, la->la.la_flags);
2291.30Shans}
2301.30Shans
2311.30Shansstatic void
2321.30Shansdec_6600_mcheck_sys(unsigned int indent, struct ev6_logout_area *la)
2331.30Shans{
2341.33Smatt	struct ev6_logout_sys *ls =
2351.30Shans		(struct ev6_logout_sys *)ALPHA_LOGOUT_SYSTEM_AREA(&la->la);
2361.30Shans
2371.30Shans#define FMT	"%-30s = 0x%016lx\n"
2381.30Shans
2391.30Shans	IPRINTF(indent, FMT, "Software Error Summary Flags", ls->flags);
2401.30Shans
2411.30Shans	IPRINTF(indent, FMT, "CPU Device Interrupt Requests", ls->dir);
2421.30Shans	tsc_print_dir(indent + 1, ls->dir);
2431.30Shans
2441.30Shans	IPRINTF(indent, FMT, "Cchip Miscellaneous Register", ls->misc);
2451.30Shans	tsc_print_misc(indent + 1, ls->misc);
2461.30Shans
2471.30Shans	IPRINTF(indent, FMT, "Pchip 0 Error Register", ls->p0_error);
2481.30Shans	if (ls->flags & 0x5)
2491.30Shans		tsp_print_error(indent + 1, ls->p0_error);
2501.30Shans
2511.30Shans	IPRINTF(indent, FMT, "Pchip 1 Error Register", ls->p1_error);
2521.30Shans	if (ls->flags & 0x6)
2531.30Shans		tsp_print_error(indent + 1, ls->p1_error);
2541.30Shans}
2551.30Shans
2561.30Shansstatic void
2571.30Shansdec_6600_mcheck_handler(unsigned long mces, struct trapframe *framep,
2581.30Shans			unsigned long vector, unsigned long param)
2591.30Shans{
2601.30Shans	struct mchkinfo *mcp;
2611.30Shans	struct ev6_logout_area *la = (struct ev6_logout_area *)param;
2621.30Shans
2631.30Shans	/*
2641.30Shans	 * If we expected a machine check, just go handle it in common code.
2651.30Shans	 */
2661.30Shans	mcp = &curcpu()->ci_mcinfo;
2671.33Smatt	if (mcp->mc_expected)
2681.30Shans		machine_check(mces, framep, vector, param);
2691.30Shans
2701.30Shans	dec_6600_mcheck(vector, la);
2711.30Shans
2721.30Shans	switch (vector) {
2731.30Shans	case ALPHA_SYS_ERROR:
2741.30Shans	case ALPHA_SYS_MCHECK:
2751.30Shans		dec_6600_mcheck_sys(1, la);
2761.30Shans		break;
2771.30Shans
2781.30Shans	}
2791.30Shans
2801.30Shans	machine_check(mces, framep, vector, param);
2811.30Shans}
282