dec_6600.c revision 1.40
1/* $NetBSD: dec_6600.c,v 1.40 2025/10/03 14:12:03 thorpej Exp $ */ 2 3/* 4 * Copyright (c) 1995, 1996, 1997 Carnegie-Mellon University. 5 * All rights reserved. 6 * 7 * Author: Chris G. Demetriou 8 * 9 * Permission to use, copy, modify and distribute this software and 10 * its documentation is hereby granted, provided that both the copyright 11 * notice and this permission notice appear in all copies of the 12 * software, derivative works or modified versions, and any portions 13 * thereof, and that both notices appear in supporting documentation. 14 * 15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 17 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 18 * 19 * Carnegie Mellon requests users of this software to return to 20 * 21 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 22 * School of Computer Science 23 * Carnegie Mellon University 24 * Pittsburgh PA 15213-3890 25 * 26 * any improvements or extensions that they make and grant Carnegie the 27 * rights to redistribute these changes. 28 */ 29 30#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 31 32__KERNEL_RCSID(0, "$NetBSD: dec_6600.c,v 1.40 2025/10/03 14:12:03 thorpej Exp $"); 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/device.h> 37#include <sys/lwp.h> 38 39#include <machine/rpb.h> 40#include <machine/autoconf.h> 41#include <machine/cpuconf.h> 42#include <machine/alpha.h> 43#include <machine/logout.h> 44 45#include <dev/pci/pcivar.h> 46 47#include <alpha/pci/tsreg.h> 48#include <alpha/pci/tsvar.h> 49 50#define DR_VERBOSE(f) while (0) 51 52void dec_6600_init(void); 53static void dec_6600_cons_init(void); 54static void dec_6600_device_register(device_t, void *); 55static void dec_6600_mcheck(unsigned long, struct ev6_logout_area *); 56static void dec_6600_mcheck_sys(unsigned int, struct ev6_logout_area *); 57static void dec_6600_mcheck_handler(unsigned long, struct trapframe *, 58 unsigned long, unsigned long); 59 60static const struct alpha_variation_table dec_6600_variations[] = { 61 { SV_ST_DP264, "AlphaPC DP264" }, 62 { SV_ST_CLIPPER, "AlphaServer ES40 (\"Clipper\")" }, 63 { SV_ST_GOLDRUSH, "AlphaServer DS20 (\"GoldRush\")" }, 64 { SV_ST_WEBBRICK, "AlphaServer DS10 (\"WebBrick\")" }, 65 { SV_ST_SHARK, "AlphaServer DS20L (\"Shark\")" }, 66 { 0, NULL }, 67}; 68 69static const struct alpha_variation_table dec_titan_variations[] = { 70 { 0, NULL }, 71}; 72 73void 74dec_6600_init(void) 75{ 76 uint64_t variation; 77 78 platform.family = (hwrpb->rpb_type == ST_DEC_TITAN) ? "Titan" 79 : "6600"; 80 81 if ((platform.model = alpha_dsr_sysname()) == NULL) { 82 const struct alpha_variation_table *vartab = 83 (hwrpb->rpb_type == ST_DEC_TITAN) ? dec_titan_variations 84 : dec_6600_variations; 85 variation = hwrpb->rpb_variation & SV_ST_MASK; 86 if ((platform.model = alpha_variation_name(variation, 87 vartab)) == NULL) { 88 platform.model = alpha_unknown_sysname(); 89 } 90 } 91 92 platform.iobus = "tsc"; 93 platform.cons_init = dec_6600_cons_init; 94 platform.device_register = dec_6600_device_register; 95 platform.mcheck_handler = dec_6600_mcheck_handler; 96 97 /* enable Cchip and Pchip error interrupts */ 98 STQP(TS_C_DIM0) = 0xe000000000000000; 99 STQP(TS_C_DIM1) = 0xe000000000000000; 100} 101 102static void 103dec_6600_cons_init(void) 104{ 105 struct ctb *ctb; 106 uint64_t ctbslot; 107 struct tsp_config *tsp; 108 bus_space_tag_t isa_iot, isa_memt; 109 110 ctb = (struct ctb *)(((char *)hwrpb) + hwrpb->rpb_ctb_off); 111 ctbslot = ctb->ctb_turboslot; 112 113 /* Console hose defaults to hose 0. */ 114 tsp_console_hose = 0; 115 116 tsp = tsp_init(tsp_console_hose); 117 118 isa_iot = &tsp->pc_iot; 119 isa_memt = &tsp->pc_memt; 120 121 switch (ctb->ctb_term_type) { 122 case CTB_PRINTERPORT: 123 /* serial console ... */ 124 assert(CTB_TURBOSLOT_HOSE(ctbslot) == 0); 125 break; 126 127 case CTB_GRAPHICS: 128 /* PCI display might be on a different hose. */ 129 if (CTB_TURBOSLOT_TYPE(ctbslot) != CTB_TURBOSLOT_TYPE_ISA) { 130 tsp_console_hose = CTB_TURBOSLOT_HOSE(ctbslot); 131 tsp = tsp_init(tsp_console_hose); 132 } 133 break; 134 135 default: 136 /* Let pci_consinit() handle it. */ 137 break; 138 } 139 140 pci_consinit(&tsp->pc_pc, &tsp->pc_iot, &tsp->pc_memt, 141 isa_iot, isa_memt); 142} 143 144static void 145dec_6600_device_register(device_t dev, void *aux) 146{ 147 static device_t primarydev; 148 struct bootdev_data *b = bootdev_data; 149 device_t parent = device_parent(dev); 150 151 /* 152 * First section: Deal with system-specific quirks. 153 */ 154 155 if ((hwrpb->rpb_variation & SV_ST_MASK) == SV_ST_WEBBRICK) { 156 /* 157 * DMA on the on-board ALI IDE controller is not 158 * working correctly; disable it for now to let 159 * the systems at least hobble along. 160 * 161 * N.B. There's only one Pchip on a DS10, do there 162 * is not need to determine which hose we have here. 163 * 164 * XXX This is meant to be temporary until we can find 165 * XXX and fix the issue with bus-master DMA. 166 */ 167 if (device_is_a(parent, "pci") && device_is_a(dev, "aceride")) { 168 struct pci_attach_args *pa = aux; 169 170 if (pa->pa_bus == 0 && pa->pa_device == 13 && 171 pa->pa_function == 0) { 172 device_setprop_bool(dev, 173 "pciide-disable-dma", true); 174 } 175 } 176 } 177 178 /* 179 * Second section: Boot device detection. 180 */ 181 182 if (booted_device != NULL || b == NULL) { 183 return; 184 } 185 186 if (primarydev == NULL) { 187 if (device_is_a(dev, "tsp")) { 188 struct tsp_attach_args *tsp = aux; 189 190 if (b->bus == tsp->tsp_slot) { 191 primarydev = dev; 192 DR_VERBOSE(printf("\nprimarydev = %s\n", 193 device_xname(dev))); 194 } 195 } 196 return; 197 } 198 199 pci_find_bootdev(primarydev, dev, aux); 200} 201 202static void 203dec_6600_mcheck(unsigned long vector, struct ev6_logout_area *la) 204{ 205 const char *t = "Unknown", *c = ""; 206 207 if (vector == ALPHA_SYS_ERROR || vector == ALPHA_PROC_ERROR) 208 c = " Correctable"; 209 210 switch (vector) { 211 case ALPHA_SYS_ERROR: 212 case ALPHA_SYS_MCHECK: 213 t = "System"; 214 break; 215 216 case ALPHA_PROC_ERROR: 217 case ALPHA_PROC_MCHECK: 218 t = "Processor"; 219 break; 220 221 case ALPHA_ENV_MCHECK: 222 t = "Environmental"; 223 break; 224 } 225 226 printf("\n%s%s Machine Check (%lx): " 227 "Rev 0x%x, Code 0x%x, Flags 0x%x\n\n", 228 t, c, vector, la->mchk_rev, la->mchk_code, la->la.la_flags); 229} 230 231static void 232dec_6600_mcheck_sys(unsigned int indent, struct ev6_logout_area *la) 233{ 234 struct ev6_logout_sys *ls = 235 (struct ev6_logout_sys *)ALPHA_LOGOUT_SYSTEM_AREA(&la->la); 236 237#define FMT "%-30s = 0x%016lx\n" 238 239 IPRINTF(indent, FMT, "Software Error Summary Flags", ls->flags); 240 241 IPRINTF(indent, FMT, "CPU Device Interrupt Requests", ls->dir); 242 tsc_print_dir(indent + 1, ls->dir); 243 244 IPRINTF(indent, FMT, "Cchip Miscellaneous Register", ls->misc); 245 tsc_print_misc(indent + 1, ls->misc); 246 247 IPRINTF(indent, FMT, "Pchip 0 Error Register", ls->p0_error); 248 if (ls->flags & 0x5) 249 tsp_print_error(indent + 1, ls->p0_error); 250 251 IPRINTF(indent, FMT, "Pchip 1 Error Register", ls->p1_error); 252 if (ls->flags & 0x6) 253 tsp_print_error(indent + 1, ls->p1_error); 254} 255 256static void 257dec_6600_mcheck_handler(unsigned long mces, struct trapframe *framep, 258 unsigned long vector, unsigned long param) 259{ 260 struct mchkinfo *mcp; 261 struct ev6_logout_area *la = (struct ev6_logout_area *)param; 262 263 /* 264 * If we expected a machine check, just go handle it in common code. 265 */ 266 mcp = &curcpu()->ci_mcinfo; 267 if (mcp->mc_expected) 268 machine_check(mces, framep, vector, param); 269 270 dec_6600_mcheck(vector, la); 271 272 switch (vector) { 273 case ALPHA_SYS_ERROR: 274 case ALPHA_SYS_MCHECK: 275 dec_6600_mcheck_sys(1, la); 276 break; 277 278 } 279 280 machine_check(mces, framep, vector, param); 281} 282