1/* $NetBSD: dec_2100_a50.c,v 1.65 2011/07/01 19:22:35 dyoung 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 * Additional Copyright (c) 1997 by Matthew Jacob for NASA/Ames Research Center 31 */ 32 33#include "opt_kgdb.h" 34 35#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 36 37__KERNEL_RCSID(0, "$NetBSD: dec_2100_a50.c,v 1.65 2011/07/01 19:22:35 dyoung Exp $"); 38 39#include <sys/param.h> 40#include <sys/systm.h> 41#include <sys/device.h> 42#include <sys/termios.h> 43#include <sys/conf.h> 44#include <dev/cons.h> 45 46#include <machine/rpb.h> 47#include <machine/alpha.h> 48#include <machine/autoconf.h> 49#include <machine/cpuconf.h> 50#include <sys/bus.h> 51 52#include <dev/ic/comreg.h> 53#include <dev/ic/comvar.h> 54 55#include <dev/isa/isareg.h> 56#include <dev/isa/isavar.h> 57#include <dev/ic/i8042reg.h> 58#include <dev/ic/pckbcvar.h> 59#include <dev/pci/pcireg.h> 60#include <dev/pci/pcivar.h> 61 62#include <alpha/pci/apecsreg.h> 63#include <alpha/pci/apecsvar.h> 64#include <machine/logout.h> 65 66#include <dev/scsipi/scsi_all.h> 67#include <dev/scsipi/scsipi_all.h> 68#include <dev/scsipi/scsiconf.h> 69 70#include "pckbd.h" 71 72#ifndef CONSPEED 73#define CONSPEED TTYDEF_SPEED 74#endif 75static int comcnrate = CONSPEED; 76 77void dec_2100_a50_init(void); 78static void dec_2100_a50_cons_init(void); 79static void dec_2100_a50_device_register(device_t, void *); 80 81static void dec_2100_a50_mcheck_handler 82(unsigned long, struct trapframe *, unsigned long, unsigned long); 83 84static void dec_2100_a50_mcheck(unsigned long, unsigned long, 85 unsigned long, struct trapframe *); 86 87 88#ifdef KGDB 89#include <machine/db_machdep.h> 90 91static const char *kgdb_devlist[] = { 92 "com", 93 NULL, 94}; 95#endif /* KGDB */ 96 97const struct alpha_variation_table dec_2100_a50_variations[] = { 98 { SV_ST_AVANTI, "AlphaStation 400 4/233 (\"Avanti\")" }, 99 { SV_ST_MUSTANG2_4_166, "AlphaStation 200 4/166 (\"Mustang II\")" }, 100 { SV_ST_MUSTANG2_4_233, "AlphaStation 200 4/233 (\"Mustang II\")" }, 101 { SV_ST_AVANTI_4_266, "AlphaStation 250 4/266" }, 102 { SV_ST_MUSTANG2_4_100, "AlphaStation 200 4/100 (\"Mustang II\")" }, 103 { SV_ST_AVANTI_4_233, "AlphaStation 255/233" }, 104 { 0, NULL }, 105}; 106 107void 108dec_2100_a50_init(void) 109{ 110 uint64_t variation; 111 112 platform.family = "AlphaStation 200/400 (\"Avanti\")"; 113 114 if ((platform.model = alpha_dsr_sysname()) == NULL) { 115 variation = hwrpb->rpb_variation & SV_ST_MASK; 116 if (variation == SV_ST_AVANTI_XXX) { 117 /* XXX apparently the same? */ 118 variation = SV_ST_AVANTI; 119 } 120 if ((platform.model = alpha_variation_name(variation, 121 dec_2100_a50_variations)) == NULL) 122 platform.model = alpha_unknown_sysname(); 123 } 124 125 platform.iobus = "apecs"; 126 platform.cons_init = dec_2100_a50_cons_init; 127 platform.device_register = dec_2100_a50_device_register; 128 platform.mcheck_handler = dec_2100_a50_mcheck_handler; 129 130} 131 132static void 133dec_2100_a50_cons_init(void) 134{ 135 struct ctb *ctb; 136 struct apecs_config *acp; 137 extern struct apecs_config apecs_configuration; 138 139 acp = &apecs_configuration; 140 apecs_init(acp, 0); 141 142 ctb = (struct ctb *)(((char *)hwrpb) + hwrpb->rpb_ctb_off); 143 144 switch (ctb->ctb_term_type) { 145 case CTB_PRINTERPORT: 146 /* serial console ... */ 147 /* XXX */ 148 { 149 /* 150 * Delay to allow PROM putchars to complete. 151 * FIFO depth * character time, 152 * character time = (1000000 / (defaultrate / 10)) 153 */ 154 DELAY(160000000 / comcnrate); 155 156 if(comcnattach(&acp->ac_iot, 0x3f8, comcnrate, 157 COM_FREQ, COM_TYPE_NORMAL, 158 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8)) 159 panic("can't init serial console"); 160 161 break; 162 } 163 164 case CTB_GRAPHICS: 165#if NPCKBD > 0 166 /* display console ... */ 167 /* XXX */ 168 (void) pckbc_cnattach(&acp->ac_iot, IO_KBD, KBCMDP, 169 PCKBC_KBD_SLOT); 170 171 if (CTB_TURBOSLOT_TYPE(ctb->ctb_turboslot) == 172 CTB_TURBOSLOT_TYPE_ISA) 173 isa_display_console(&acp->ac_iot, &acp->ac_memt); 174 else 175 pci_display_console(&acp->ac_iot, &acp->ac_memt, 176 &acp->ac_pc, CTB_TURBOSLOT_BUS(ctb->ctb_turboslot), 177 CTB_TURBOSLOT_SLOT(ctb->ctb_turboslot), 0); 178#else 179 panic("not configured to use display && keyboard console"); 180#endif 181 break; 182 183 default: 184 printf("ctb->ctb_term_type = 0x%lx\n", ctb->ctb_term_type); 185 printf("ctb->ctb_turboslot = 0x%lx\n", ctb->ctb_turboslot); 186 187 panic("consinit: unknown console type %ld", 188 ctb->ctb_term_type); 189 } 190#ifdef KGDB 191 /* Attach the KGDB device. */ 192 alpha_kgdb_init(kgdb_devlist, &acp->ac_iot); 193#endif /* KGDB */ 194} 195 196static void 197dec_2100_a50_device_register(device_t dev, void *aux) 198{ 199 static int found, initted, diskboot, netboot; 200 static device_t pcidev, ctrlrdev; 201 struct bootdev_data *b = bootdev_data; 202 device_t parent = device_parent(dev); 203 204 if (found) 205 return; 206 207 if (!initted) { 208 diskboot = (strcasecmp(b->protocol, "SCSI") == 0); 209 netboot = (strcasecmp(b->protocol, "BOOTP") == 0) || 210 (strcasecmp(b->protocol, "MOP") == 0); 211#if 0 212 printf("diskboot = %d, netboot = %d\n", diskboot, netboot); 213#endif 214 initted =1; 215 } 216 217 if (pcidev == NULL) { 218 if (!device_is_a(dev, "pci")) 219 return; 220 else { 221 struct pcibus_attach_args *pba = aux; 222 223 if ((b->slot / 1000) != pba->pba_bus) 224 return; 225 226 pcidev = dev; 227#if 0 228 printf("\npcidev = %s\n", device_xname(dev)); 229#endif 230 return; 231 } 232 } 233 234 if (ctrlrdev == NULL) { 235 if (parent != pcidev) 236 return; 237 else { 238 struct pci_attach_args *pa = aux; 239 int slot; 240 241 slot = pa->pa_bus * 1000 + pa->pa_function * 100 + 242 pa->pa_device; 243 if (b->slot != slot) 244 return; 245 246 if (netboot) { 247 booted_device = dev; 248#if 0 249 printf("\nbooted_device = %s\n", device_xname(dev)); 250#endif 251 found = 1; 252 } else { 253 ctrlrdev = dev; 254#if 0 255 printf("\nctrlrdev = %s\n", device_xname(dev)); 256#endif 257 } 258 return; 259 } 260 } 261 262 if (!diskboot) 263 return; 264 265 if (device_is_a(dev, "sd") || 266 device_is_a(dev, "st") || 267 device_is_a(dev, "cd")) { 268 struct scsipibus_attach_args *sa = aux; 269 struct scsipi_periph *periph = sa->sa_periph; 270 int unit; 271 272 if (device_parent(parent) != ctrlrdev) 273 return; 274 275 unit = periph->periph_target * 100 + periph->periph_lun; 276 if (b->unit != unit) 277 return; 278 if (b->channel != periph->periph_channel->chan_channel) 279 return; 280 281 /* we've found it! */ 282 booted_device = dev; 283#if 0 284 printf("\nbooted_device = %s\n", device_xname(dev)); 285#endif 286 found = 1; 287 } 288} 289 290 291static void 292dec_2100_a50_mcheck(unsigned long mces, unsigned long type, unsigned long logout, struct trapframe *framep) 293{ 294 struct mchkinfo *mcp; 295 static const char *fmt1 = " %-25s = 0x%016lx\n"; 296 int i, sysaddr; 297 mc_hdr_avanti *hdr; 298 mc_uc_avanti *ptr; 299 300 /* 301 * If we expected a machine check, just go handle it in common code. 302 */ 303 mcp = &curcpu()->ci_mcinfo; 304 if (mcp->mc_expected) { 305 machine_check(mces, framep, type, logout); 306 return; 307 } 308 309 hdr = (mc_hdr_avanti *) logout; 310 ptr = (mc_uc_avanti *) (logout + sizeof (*hdr)); 311 312 printf(" Processor Machine Check (%lx), Code 0x%lx\n", 313 type, hdr->mcheck_code); 314 printf("CPU state:\n"); 315 /* Print PAL fields */ 316 for (i = 0; i < 32; i += 2) { 317 printf("\tPAL temp[%d-%d]\t\t= 0x%16lx 0x%16lx\n", i, i+1, 318 ptr->paltemp[i], ptr->paltemp[i+1]); 319 } 320 printf(fmt1, "Excepting Instruction Addr", ptr->exc_addr); 321 printf(fmt1, "Summary of arithmetic traps", ptr->exc_sum); 322 printf(fmt1, "Exception mask", ptr->exc_mask); 323 printf(fmt1, "ICCSR", ptr->iccsr); 324 printf(fmt1, "Base address for PALcode", ptr->pal_base); 325 printf(fmt1, "HIER", ptr->hier); 326 printf(fmt1, "HIRR", ptr->hirr); 327 printf(fmt1, "MM_CSR", ptr->mm_csr); 328 printf(fmt1, "DC_STAT", ptr->dc_stat); 329 printf(fmt1, "DC_ADDR", ptr->dc_addr); 330 printf(fmt1, "ABOX_CTL", ptr->abox_ctl); 331 printf(fmt1, "Bus Interface Unit status", ptr->biu_stat); 332 printf(fmt1, "Bus Interface Unit addr", ptr->biu_addr); 333 printf(fmt1, "Bus Interface Unit control", ptr->biu_ctl); 334 printf(fmt1, "Fill Syndrome", ptr->fill_syndrome); 335 printf(fmt1, "Fill Address", ptr->fill_addr); 336 printf(fmt1, "Effective VA", ptr->va); 337 printf(fmt1, "BC_TAG", ptr->bc_tag); 338 339 printf("\nCache and Memory Controller (21071-CA) state:\n"); 340 printf(fmt1, "COMA_GCR", ptr->coma_gcr); 341 printf(fmt1, "COMA_EDSR", ptr->coma_edsr); 342 printf(fmt1, "COMA_TER", ptr->coma_ter); 343 printf(fmt1, "COMA_ELAR", ptr->coma_elar); 344 printf(fmt1, "COMA_EHAR", ptr->coma_ehar); 345 printf(fmt1, "COMA_LDLR", ptr->coma_ldlr); 346 printf(fmt1, "COMA_LDHR", ptr->coma_ldhr); 347 printf(fmt1, "COMA_BASE0", ptr->coma_base0); 348 printf(fmt1, "COMA_BASE1", ptr->coma_base1); 349 printf(fmt1, "COMA_BASE2", ptr->coma_base2); 350 printf(fmt1, "COMA_CNFG0", ptr->coma_cnfg0); 351 printf(fmt1, "COMA_CNFG1", ptr->coma_cnfg1); 352 printf(fmt1, "COMA_CNFG2", ptr->coma_cnfg2); 353 354 printf("\nPCI bridge (21071-DA) state:\n"); 355 356 printf(fmt1, "EPIC Diag. control/status", ptr->epic_dcsr); 357 printf(fmt1, "EPIC_PEAR", ptr->epic_pear); 358 printf(fmt1, "EPIC_SEAR", ptr->epic_sear); 359 printf(fmt1, "EPIC_TBR1", ptr->epic_tbr1); 360 printf(fmt1, "EPIC_TBR2", ptr->epic_tbr2); 361 printf(fmt1, "EPIC_PBR1", ptr->epic_pbr1); 362 printf(fmt1, "EPIC_PBR2", ptr->epic_pbr2); 363 printf(fmt1, "EPIC_PMR1", ptr->epic_pmr1); 364 printf(fmt1, "EPIC_PMR2", ptr->epic_pmr2); 365 printf(fmt1, "EPIC_HARX1", ptr->epic_harx1); 366 printf(fmt1, "EPIC_HARX2", ptr->epic_harx2); 367 printf(fmt1, "EPIC_PMLT", ptr->epic_pmlt); 368 printf(fmt1, "EPIC_TAG0", ptr->epic_tag0); 369 printf(fmt1, "EPIC_TAG1", ptr->epic_tag1); 370 printf(fmt1, "EPIC_TAG2", ptr->epic_tag2); 371 printf(fmt1, "EPIC_TAG3", ptr->epic_tag3); 372 printf(fmt1, "EPIC_TAG4", ptr->epic_tag4); 373 printf(fmt1, "EPIC_TAG5", ptr->epic_tag5); 374 printf(fmt1, "EPIC_TAG6", ptr->epic_tag6); 375 printf(fmt1, "EPIC_TAG7", ptr->epic_tag7); 376 printf(fmt1, "EPIC_DATA0", ptr->epic_data0); 377 printf(fmt1, "EPIC_DATA1", ptr->epic_data1); 378 printf(fmt1, "EPIC_DATA2", ptr->epic_data2); 379 printf(fmt1, "EPIC_DATA3", ptr->epic_data3); 380 printf(fmt1, "EPIC_DATA4", ptr->epic_data4); 381 printf(fmt1, "EPIC_DATA5", ptr->epic_data5); 382 printf(fmt1, "EPIC_DATA6", ptr->epic_data6); 383 printf(fmt1, "EPIC_DATA7", ptr->epic_data7); 384 385 printf("\n"); 386 387 if (type == ALPHA_SYS_MCHECK) { 388 printf("\nPCI bridge fault\n"); 389 switch(hdr->mcheck_code) { 390 case AVANTI_RETRY_TIMEOUT: 391 printf("\tRetry timeout error accessing 0x%08lx.\n", 392 ptr->epic_pear & 0xffffffff); 393 break; 394 395 case AVANTI_DMA_DATA_PARITY: 396 printf("\tDMA data parity error accessing 0x%08lx.\n", 397 ptr->epic_pear & 0xffffffff); 398 break; 399 400 case AVANTI_IO_PARITY: 401 printf("\tI/O parity error at 0x%08lx during PCI cycle 0x%0lx.\n", 402 ptr->epic_pear & 0xffffffff, 403 (ptr->epic_dcsr >> 18) & 0xf); 404 break; 405 406 case AVANTI_TARGET_ABORT: 407 printf("\tPCI target abort at 0x%08lx during PCI cycle 0x%0lx.\n", 408 ptr->epic_pear & 0xffffffff, 409 (ptr->epic_dcsr >> 18) & 0xf); 410 break; 411 412 case AVANTI_NO_DEVICE: 413 printf("\tNo device responded at 0x%08lx during PCI cycle 0x%0lx\n.", 414 ptr->epic_pear & 0xffffffff, 415 (ptr->epic_dcsr >> 18) & 0xf); 416 break; 417 418 case AVANTI_CORRRECTABLE_MEMORY: 419 printf("\tCorrectable memory error reported.\n" 420 "\tWARNING ECC not implemented on this system!\n" 421 "\tError is incorrect.\n"); 422 break; 423 424 case AVANTI_UNCORRECTABLE_PCI_MEMORY: 425 printf("\tUncorrectable memory error at %016lx reported " 426 "during DMA read.\n", 427 (ptr->epic_sear & 0xfffffff0) << 2); 428 break; 429 430 case AVANTI_INVALID_PT_LOOKUP: 431 printf("\tInvalid page table lookup during scatter/gather.\n" ); 432 if (ptr->epic_dcsr & 0xf20) 433 printf("\tAddress lost.\n"); 434 else 435 printf("\tBus address to 0x%08lx, PCI cycle 0x%0lx\n", 436 ptr->epic_pear & 0xffffffff, 437 (ptr->epic_dcsr >> 18) & 0xf); 438 break; 439 440 case AVANTI_MEMORY: 441 printf("\tMemory error at %016lx, ", 442 (ptr->epic_sear & 0xfffffff0) << 2); 443 sysaddr = (ptr->epic_sear & 0xffffffff) >> 21; 444 if (sysaddr >= ((ptr->coma_base0 >> 5) & 0x7ff) && 445 sysaddr < (((ptr->coma_base0 >> 5) & 0x7ff) + 446 (1 << (7 - (ptr->coma_cnfg0 >> 1))))) 447 printf("SIMM bank 0\n"); 448 else if (sysaddr >= ((ptr->coma_base1 >> 5) & 0x7ff) && 449 sysaddr < (((ptr->coma_base1 >> 5) & 0x7ff) + 450 (1 << (7 - (ptr->coma_cnfg1 >> 1))))) 451 printf("SIMM bank 1\n"); 452 else if (sysaddr >= ((ptr->coma_base2 >> 5) & 0x7ff) && 453 sysaddr < (((ptr->coma_base2 >> 5) & 0x7ff) + 454 (1 << (7 - (ptr->coma_cnfg2 >> 1))))) 455 printf("SIMM bank 2\n"); 456 else 457 printf("invalid memory bank?\n"); 458 break; 459 460 case AVANTI_BCACHE_TAG_ADDR_PARITY: 461 printf("\tBcache tag address parity error, caused by "); 462 if (ptr->coma_edsr & 0x20) 463 printf("victim write\n"); 464 else if (ptr->coma_edsr & 0x10) 465 printf("DMA. ioCmd<2:0> = %0lx\n", (ptr->coma_edsr >> 6) & 7); 466 else 467 printf("CPU. cpuCReq<2:0> = %0lx\n", (ptr->coma_edsr >> 6) & 7); 468 break; 469 470 case AVANTI_BCACHE_TAG_CTRL_PARITY: 471 printf("\tBcache tag control parity error, caused by "); 472 if (ptr->coma_edsr & 0x20) 473 printf("victim write\n"); 474 else if (ptr->coma_edsr & 0x10) 475 printf("DMA. ioCmd<2:0> = %0lx\n", (ptr->coma_edsr >> 6) & 7); 476 else 477 printf("CPU. cpuCReq<2:0> = %0lx\n", (ptr->coma_edsr >> 6) & 7); 478 break; 479 480 case AVANTI_NONEXISTENT_MEMORY: 481 printf("\tNonexistent memory error, caused by "); 482 if (ptr->coma_edsr & 0x20) 483 printf("victim write\n"); 484 else if (ptr->coma_edsr & 0x10) 485 printf("DMA. ioCmd<2:0> = %0lx\n", (ptr->coma_edsr >> 6) & 7); 486 else 487 printf("CPU. cpuCReq<2:0> = %0lx\n", (ptr->coma_edsr >> 6) & 7); 488 break; 489 490 case AVANTI_IO_BUS: 491 printf("\tI/O bus error at %08lx during PCI cycle %0lx\n", 492 ptr->epic_pear & 0xffffffff, (ptr->epic_dcsr >> 18) & 0xf); 493 break; 494 495 case AVANTI_BCACHE_TAG_PARITY: 496 printf("\tBcache tag address parity error.\n" 497 "\tcReg_h cycle %0lx, address<7:0> 0x%02lx\n", 498 (ptr->biu_stat >> 4) & 7, 499 ptr->biu_addr & 0xff); 500 break; 501 502 case AVANTI_BCACHE_TAG_CTRL_PARITY2: 503 printf("\tBcache tag control parity error.\n" 504 "\tcReg_h cycle %0lx, address<7:0> 0x%02lx\n", 505 (ptr->biu_stat >> 4) & 7, 506 ptr->biu_addr & 0xff); 507 break; 508 509 } 510 } else { /* ALPHA_PROC_MCHECK */ 511 printf("\nProcessor fault\n"); 512 switch(hdr->mcheck_code) { 513 case AVANTI_HARD_ERROR: 514 printf("\tHard error cycle.\n"); 515 break; 516 517 case AVANTI_CORRECTABLE_ECC: 518 printf("\tCorrectable ECC error.\n" 519 "\tWARNING ECC not implemented on this system!\n" 520 "\tError is incorrect.\n"); 521 break; 522 523 case AVANTI_NONCORRECTABLE_ECC: 524 printf("\tNoncorrectable ECC error.\n" 525 "\tWARNING ECC not implemented on this system!\n" 526 "\tError is incorrect.\n"); 527 break; 528 529 case AVANTI_UNKNOWN_ERROR: 530 printf("\tUnknown error.\n"); 531 break; 532 533 case AVANTI_SOFT_ERROR: 534 printf("\tSoft error cycle.\n"); 535 break; 536 537 case AVANTI_BUGCHECK: 538 printf("\tBugcheck.\n"); 539 break; 540 541 case AVANTI_OS_BUGCHECK: 542 printf("\tOS Bugcheck.\n"); 543 break; 544 545 case AVANTI_DCACHE_FILL_PARITY: 546 printf("\tPrimary Dcache data fill parity error.\n" 547 "\tDcache Quadword %lx, address %08lx\n", 548 (ptr->biu_stat >> 12) & 0x3, 549 (ptr->fill_addr >> 8) & 0x7f); 550 break; 551 552 case AVANTI_ICACHE_FILL_PARITY: 553 printf("\tPrimary Icache data fill parity error.\n" 554 "\tDcache Quadword %lx, address %08lx\n", 555 (ptr->biu_stat >> 12) & 0x3, 556 (ptr->fill_addr >> 8) & 0x7f); 557 break; 558 } 559 } 560 561 /* 562 * Now that we've printed all sorts of useful information 563 * and have decided that we really can't do any more to 564 * respond to the error, go on to the common code for 565 * final disposition. Usually this means that we die. 566 */ 567 /* 568 * XXX: HANDLE PCI ERRORS HERE? 569 */ 570 machine_check(mces, framep, type, logout); 571} 572 573static void 574dec_2100_a50_mcheck_handler(unsigned long mces, struct trapframe *framep, unsigned long vector, unsigned long param) 575{ 576 switch (vector) { 577 case ALPHA_SYS_MCHECK: 578 case ALPHA_PROC_MCHECK: 579 dec_2100_a50_mcheck(mces, vector, param, framep); 580 break; 581 default: 582 printf("2100_A50_MCHECK: unknown check vector 0x%lx\n", vector); 583 machine_check(mces, framep, vector, param); 584 break; 585 } 586} 587