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