1 /* $NetBSD: dec_2100_a500.c,v 1.19 2009/09/14 02:46:29 mhitch Exp $ */ 2 3 /*- 4 * Copyright (c) 1999 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1995, 1996, 1997 Carnegie-Mellon University. 34 * All rights reserved. 35 * 36 * Author: Chris G. Demetriou 37 * 38 * Permission to use, copy, modify and distribute this software and 39 * its documentation is hereby granted, provided that both the copyright 40 * notice and this permission notice appear in all copies of the 41 * software, derivative works or modified versions, and any portions 42 * thereof, and that both notices appear in supporting documentation. 43 * 44 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 45 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 46 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 47 * 48 * Carnegie Mellon requests users of this software to return to 49 * 50 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 51 * School of Computer Science 52 * Carnegie Mellon University 53 * Pittsburgh PA 15213-3890 54 * 55 * any improvements or extensions that they make and grant Carnegie the 56 * rights to redistribute these changes. 57 */ 58 59 #include "opt_kgdb.h" 60 61 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 62 63 __KERNEL_RCSID(0, "$NetBSD: dec_2100_a500.c,v 1.19 2009/09/14 02:46:29 mhitch Exp $"); 64 65 #include <sys/param.h> 66 #include <sys/systm.h> 67 #include <sys/device.h> 68 #include <sys/termios.h> 69 #include <sys/conf.h> 70 #include <dev/cons.h> 71 72 #include <machine/rpb.h> 73 #include <machine/autoconf.h> 74 #include <machine/cpuconf.h> 75 #include <machine/bus.h> 76 #include <machine/alpha.h> 77 78 #include <dev/ic/comreg.h> 79 #include <dev/ic/comvar.h> 80 81 #include <dev/isa/isareg.h> 82 #include <dev/isa/isavar.h> 83 #include <dev/ic/i8042reg.h> 84 #include <dev/ic/pckbcvar.h> 85 #include <dev/pci/pcireg.h> 86 #include <dev/pci/pcivar.h> 87 88 #include <alpha/pci/ttwogareg.h> 89 #include <alpha/pci/ttwogavar.h> 90 91 #include <dev/scsipi/scsi_all.h> 92 #include <dev/scsipi/scsipi_all.h> 93 #include <dev/scsipi/scsiconf.h> 94 95 #include <dev/ic/mlxio.h> 96 #include <dev/ic/mlxvar.h> 97 98 #include "pckbd.h" 99 100 #ifndef CONSPEED 101 #define CONSPEED TTYDEF_SPEED 102 #endif 103 static int comcnrate = CONSPEED; 104 105 void _dec_2100_a500_init(void); 106 static void dec_2100_a500_cons_init(void); 107 static void dec_2100_a500_device_register(struct device *, void *); 108 static void dec_2100_a500_machine_check(unsigned long, struct trapframe *, 109 unsigned long, unsigned long); 110 111 #ifdef KGDB 112 #include <machine/db_machdep.h> 113 114 static const char *kgdb_devlist[] = { 115 "com", 116 NULL, 117 }; 118 #endif /* KGDB */ 119 120 void 121 _dec_2100_a500_init(void) 122 { 123 124 switch (cputype) { 125 case ST_DEC_2100_A500: 126 if (alpha_implver() == ALPHA_IMPLVER_EV5) 127 platform.family = "AlphaServer 2100 (\"Sable-Gamma\")"; 128 else 129 platform.family = "AlphaServer 2100 (\"Sable\")"; 130 break; 131 132 case ST_DEC_2100A_A500: 133 platform.family = "AlphaServer 2100A (\"Lynx\")"; 134 break; 135 136 default: 137 panic("dec_2100_a500_init: Not a Sable, Sable-Gamma, or Lynx?"); 138 } 139 140 if ((platform.model = alpha_dsr_sysname()) == NULL) { 141 /* XXX don't know variations yet */ 142 platform.model = alpha_unknown_sysname(); 143 } 144 145 platform.iobus = "ttwoga"; 146 platform.cons_init = dec_2100_a500_cons_init; 147 platform.device_register = dec_2100_a500_device_register; 148 platform.mcheck_handler = dec_2100_a500_machine_check; 149 } 150 151 static void 152 dec_2100_a500_cons_init(void) 153 { 154 struct ctb *ctb; 155 u_int64_t ctbslot; 156 struct ttwoga_config *tcp; 157 158 ctb = (struct ctb *)(((char *)hwrpb) + hwrpb->rpb_ctb_off); 159 ctbslot = ctb->ctb_turboslot; 160 161 tcp = ttwoga_init(0, 0); 162 163 switch (ctb->ctb_term_type) { 164 case CTB_PRINTERPORT: 165 /* serial console ... */ 166 assert(CTB_TURBOSLOT_HOSE(ctbslot) == 0); 167 /* XXX */ 168 { 169 /* 170 * Delay to allow PROM putchars to complete. 171 * FIFO depth * character time, 172 * character time = (1000000 / (defaultrate / 10)) 173 */ 174 DELAY(160000000 / comcnrate); 175 176 if(comcnattach(&tcp->tc_iot, 0x3f8, comcnrate, 177 COM_FREQ, COM_TYPE_NORMAL, 178 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8)) 179 panic("can't init serial console"); 180 181 break; 182 } 183 184 case CTB_GRAPHICS: 185 #if NPCKBD > 0 186 /* display console ... */ 187 /* XXX */ 188 (void) pckbc_cnattach(&tcp->tc_iot, IO_KBD, KBCMDP, 189 PCKBC_KBD_SLOT); 190 191 switch (CTB_TURBOSLOT_TYPE(ctbslot)) { 192 case CTB_TURBOSLOT_TYPE_ISA: 193 /* 194 * XXX The following is apparently necessary for an 195 * XXX ISA VGA card, but what happens with real EISA 196 * XXX VGA cards? 197 */ 198 case CTB_TURBOSLOT_TYPE_EISA: 199 isa_display_console(&tcp->tc_iot, &tcp->tc_memt); 200 break; 201 202 case CTB_TURBOSLOT_TYPE_PCI: 203 /* The display PCI might be different */ 204 tcp = ttwoga_init(0, CTB_TURBOSLOT_HOSE(ctbslot)); 205 pci_display_console(&tcp->tc_iot, &tcp->tc_memt, 206 &tcp->tc_pc, CTB_TURBOSLOT_BUS(ctbslot), 207 CTB_TURBOSLOT_SLOT(ctbslot), 0); 208 break; 209 210 default: 211 printf("type = 0x%lx, hose = 0x%lx, bus = 0x%lx, " 212 "slot = 0x%lx\n", 213 CTB_TURBOSLOT_TYPE(ctbslot), 214 CTB_TURBOSLOT_HOSE(ctbslot), 215 CTB_TURBOSLOT_BUS(ctbslot), 216 CTB_TURBOSLOT_SLOT(ctbslot)); 217 panic("unknown display console type"); 218 } 219 #else 220 panic("not configured to use display && keyboard console"); 221 #endif 222 break; 223 224 default: 225 printf("ctb->ctb_term_type = 0x%lx\n", ctb->ctb_term_type); 226 printf("ctb->ctb_turboslot = 0x%lx\n", ctb->ctb_turboslot); 227 228 panic("consinit: unknown console type %ld", 229 ctb->ctb_term_type); 230 } 231 #ifdef KGDB 232 /* Attach the KGDB device. */ 233 alpha_kgdb_init(kgdb_devlist, &tcp->tc_iot); 234 #endif /* KGDB */ 235 } 236 237 static void 238 dec_2100_a500_device_register(struct device *dev, void *aux) 239 { 240 static int found, initted, diskboot, netboot; 241 static struct device *pcidev, *ctrlrdev; 242 struct bootdev_data *b = bootdev_data; 243 struct device *parent = device_parent(dev); 244 245 if (found) 246 return; 247 248 if (!initted) { 249 diskboot = (strcasecmp(b->protocol, "SCSI") == 0) || 250 (strcasecmp(b->protocol, "RAID") == 0); 251 netboot = (strcasecmp(b->protocol, "BOOTP") == 0) || 252 (strcasecmp(b->protocol, "MOP") == 0); 253 #if 0 254 printf("diskboot = %d, netboot = %d\n", diskboot, netboot); 255 #endif 256 initted =1; 257 } 258 259 if (pcidev == NULL) { 260 if (!device_is_a(dev, "pci")) 261 return; 262 else { 263 struct pcibus_attach_args *pba = aux; 264 265 if ((b->slot / 1000) != pba->pba_bus) 266 return; 267 268 pcidev = dev; 269 #if 0 270 printf("\npcidev = %s\n", dev->dv_xname); 271 #endif 272 return; 273 } 274 } 275 276 if (ctrlrdev == NULL) { 277 if (parent != pcidev) 278 return; 279 else { 280 struct pci_attach_args *pa = aux; 281 int slot; 282 283 slot = pa->pa_bus * 1000 + pa->pa_function * 100 + 284 pa->pa_device; 285 if (b->slot != slot) 286 return; 287 288 if (netboot) { 289 booted_device = dev; 290 #if 0 291 printf("\nbooted_device = %s\n", dev->dv_xname); 292 #endif 293 found = 1; 294 } else { 295 ctrlrdev = dev; 296 #if 0 297 printf("\nctrlrdev = %s\n", dev->dv_xname); 298 #endif 299 } 300 return; 301 } 302 } 303 304 if (!diskboot) 305 return; 306 307 if (device_is_a(dev, "sd") || 308 device_is_a(dev, "st") || 309 device_is_a(dev, "cd")) { 310 struct scsipibus_attach_args *sa = aux; 311 struct scsipi_periph *periph = sa->sa_periph; 312 int unit; 313 314 if (device_parent(parent) != ctrlrdev) 315 return; 316 317 unit = periph->periph_target * 100 + periph->periph_lun; 318 if (b->unit != unit) 319 return; 320 if (b->channel != periph->periph_channel->chan_channel) 321 return; 322 323 /* we've found it! */ 324 booted_device = dev; 325 #if 0 326 printf("\nbooted_device = %s\n", dev->dv_xname); 327 #endif 328 found = 1; 329 } 330 331 if (device_is_a(dev, "ld") && device_is_a(parent, "mlx")) { 332 /* 333 * Argh! The attach arguments for ld devices is not 334 * consistent, so each supported raid controller requires 335 * different checks. 336 */ 337 struct mlx_attach_args *mlxa = aux; 338 339 if (parent != ctrlrdev) 340 return; 341 342 if (b->unit != mlxa->mlxa_unit) 343 return; 344 /* we've found it! */ 345 booted_device = dev; 346 #if 0 347 printf("\nbooted_device = %s\n", dev->dv_xname); 348 #endif 349 found = 1; 350 } 351 } 352 353 /* 354 * Sable, Sable-Gamma, and Lynx machine check handlers. 355 */ 356 357 static void 358 dec_2100_a500_machine_check(unsigned long mces, struct trapframe *framep, 359 unsigned long vector, unsigned long param) 360 { 361 struct mchkinfo *mcp = &curcpu()->ci_mcinfo; 362 363 /* 364 * This is a work-around for a T2 core logic bug. See 365 * alpha/pci/ttwoga_pci.c. 366 */ 367 368 if (ttwoga_conf_cpu == cpu_number()) 369 mcp->mc_expected = 1; 370 371 machine_check(mces, framep, vector, param); 372 } 373