dec_6600.c revision 1.29
11.29Smhitch/* $NetBSD: dec_6600.c,v 1.29 2009/09/14 02:46:29 mhitch 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.1Sross * 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.1Sross * 151.1Sross * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 161.1Sross * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 171.1Sross * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 181.1Sross * 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.11Slukem#include "opt_kgdb.h" 311.11Slukem 321.1Sross#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 331.1Sross 341.29Smhitch__KERNEL_RCSID(0, "$NetBSD: dec_6600.c,v 1.29 2009/09/14 02:46:29 mhitch Exp $"); 351.1Sross 361.1Sross#include <sys/param.h> 371.1Sross#include <sys/systm.h> 381.1Sross#include <sys/device.h> 391.1Sross#include <sys/termios.h> 401.14Sgehenna#include <sys/conf.h> 411.1Sross#include <dev/cons.h> 421.1Sross 431.1Sross#include <machine/rpb.h> 441.1Sross#include <machine/autoconf.h> 451.14Sgehenna#include <machine/cpuconf.h> 461.1Sross#include <machine/bus.h> 471.1Sross 481.1Sross#include <dev/ic/comreg.h> 491.1Sross#include <dev/ic/comvar.h> 501.1Sross 511.2Sthorpej#include <dev/isa/isareg.h> 521.1Sross#include <dev/isa/isavar.h> 531.6Ssoda#include <dev/ic/i8042reg.h> 541.2Sthorpej#include <dev/ic/pckbcvar.h> 551.1Sross#include <dev/pci/pcireg.h> 561.1Sross#include <dev/pci/pcivar.h> 571.1Sross 581.1Sross#include <alpha/pci/tsreg.h> 591.1Sross#include <alpha/pci/tsvar.h> 601.1Sross 611.1Sross#include <dev/scsipi/scsi_all.h> 621.1Sross#include <dev/scsipi/scsipi_all.h> 631.1Sross#include <dev/scsipi/scsiconf.h> 641.3Sveego#include <dev/ata/atavar.h> 651.1Sross 661.29Smhitch#include <dev/ic/mlxio.h> 671.29Smhitch#include <dev/ic/mlxvar.h> 681.29Smhitch 691.29Smhitch#include <dev/i2o/i2o.h> 701.29Smhitch#include <dev/i2o/iopio.h> 711.29Smhitch#include <dev/i2o/iopvar.h> 721.29Smhitch 731.1Sross#include "pckbd.h" 741.1Sross 751.1Sross#ifndef CONSPEED 761.1Sross#define CONSPEED TTYDEF_SPEED 771.1Sross#endif 781.1Sross 791.1Sross#define DR_VERBOSE(f) while (0) 801.1Sross 811.1Srossstatic int comcnrate __attribute__((unused)) = CONSPEED; 821.1Sross 831.27Sdslvoid dec_6600_init(void); 841.27Sdslstatic void dec_6600_cons_init(void); 851.27Sdslstatic void dec_6600_device_register(struct device *, void *); 861.1Sross 871.9Sthorpej#ifdef KGDB 881.9Sthorpej#include <machine/db_machdep.h> 891.9Sthorpej 901.9Sthorpejstatic const char *kgdb_devlist[] = { 911.9Sthorpej "com", 921.9Sthorpej NULL, 931.9Sthorpej}; 941.9Sthorpej#endif /* KGDB */ 951.9Sthorpej 961.1Srossvoid 971.1Srossdec_6600_init() 981.1Sross{ 991.1Sross 1001.1Sross platform.family = "6600"; 1011.1Sross 1021.1Sross if ((platform.model = alpha_dsr_sysname()) == NULL) { 1031.1Sross /* XXX Don't know the system variations, yet. */ 1041.1Sross platform.model = alpha_unknown_sysname(); 1051.1Sross } 1061.1Sross 1071.1Sross platform.iobus = "tsc"; 1081.1Sross platform.cons_init = dec_6600_cons_init; 1091.1Sross platform.device_register = dec_6600_device_register; 1101.1Sross STQP(TS_C_DIM0) = 0UL; 1111.1Sross STQP(TS_C_DIM1) = 0UL; 1121.1Sross} 1131.1Sross 1141.1Srossstatic void 1151.1Srossdec_6600_cons_init() 1161.1Sross{ 1171.1Sross struct ctb *ctb; 1181.1Sross u_int64_t ctbslot; 1191.1Sross struct tsp_config *tsp; 1201.1Sross 1211.26Syamt ctb = (struct ctb *)(((char *)hwrpb) + hwrpb->rpb_ctb_off); 1221.1Sross ctbslot = ctb->ctb_turboslot; 1231.1Sross 1241.8Sthorpej /* Console hose defaults to hose 0. */ 1251.8Sthorpej tsp_console_hose = 0; 1261.8Sthorpej 1271.8Sthorpej tsp = tsp_init(0, tsp_console_hose); 1281.1Sross 1291.1Sross switch (ctb->ctb_term_type) { 1301.12Sthorpej case CTB_PRINTERPORT: 1311.1Sross /* serial console ... */ 1321.1Sross assert(CTB_TURBOSLOT_HOSE(ctbslot) == 0); 1331.1Sross /* XXX */ 1341.1Sross { 1351.1Sross /* 1361.1Sross * Delay to allow PROM putchars to complete. 1371.1Sross * FIFO depth * character time, 1381.1Sross * character time = (1000000 / (defaultrate / 10)) 1391.1Sross */ 1401.1Sross DELAY(160000000 / comcnrate); 1411.1Sross 1421.1Sross if(comcnattach(&tsp->pc_iot, 0x3f8, comcnrate, 1431.18Sthorpej COM_FREQ, COM_TYPE_NORMAL, 1441.1Sross (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8)) 1451.1Sross panic("can't init serial console"); 1461.1Sross 1471.1Sross break; 1481.1Sross } 1491.1Sross 1501.12Sthorpej case CTB_GRAPHICS: 1511.1Sross#if NPCKBD > 0 1521.1Sross /* display console ... */ 1531.1Sross /* XXX */ 1541.6Ssoda (void) pckbc_cnattach(&tsp->pc_iot, IO_KBD, KBCMDP, 1551.6Ssoda PCKBC_KBD_SLOT); 1561.1Sross 1571.1Sross if (CTB_TURBOSLOT_TYPE(ctbslot) == 1581.1Sross CTB_TURBOSLOT_TYPE_ISA) 1591.1Sross isa_display_console(&tsp->pc_iot, &tsp->pc_memt); 1601.1Sross else { 1611.1Sross /* The display PCI might be different */ 1621.8Sthorpej tsp_console_hose = CTB_TURBOSLOT_HOSE(ctbslot); 1631.8Sthorpej tsp = tsp_init(0, tsp_console_hose); 1641.1Sross pci_display_console(&tsp->pc_iot, &tsp->pc_memt, 1651.1Sross &tsp->pc_pc, CTB_TURBOSLOT_BUS(ctbslot), 1661.1Sross CTB_TURBOSLOT_SLOT(ctbslot), 0); 1671.1Sross } 1681.1Sross#else 1691.1Sross panic("not configured to use display && keyboard console"); 1701.1Sross#endif 1711.1Sross break; 1721.1Sross 1731.1Sross default: 1741.1Sross printf("ctb_term_type = 0x%lx ctb_turboslot = 0x%lx" 1751.1Sross " hose = %ld\n", ctb->ctb_term_type, ctbslot, 1761.1Sross CTB_TURBOSLOT_HOSE(ctbslot)); 1771.1Sross 1781.17Sprovos panic("consinit: unknown console type %ld", 1791.1Sross ctb->ctb_term_type); 1801.1Sross } 1811.9Sthorpej#ifdef KGDB 1821.9Sthorpej /* Attach the KGDB device. */ 1831.9Sthorpej alpha_kgdb_init(kgdb_devlist, &tsp->pc_iot); 1841.9Sthorpej#endif /* KGDB */ 1851.1Sross} 1861.1Sross 1871.1Srossstatic void 1881.28Sdsldec_6600_device_register(struct device *dev, void *aux) 1891.1Sross{ 1901.21Smycroft static int found, initted, diskboot, netboot; 1911.21Smycroft static struct device *primarydev, *pcidev, *ctrlrdev; 1921.1Sross struct bootdev_data *b = bootdev_data; 1931.23Sthorpej struct device *parent = device_parent(dev); 1941.1Sross 1951.1Sross if (found) 1961.1Sross return; 1971.1Sross 1981.1Sross if (!initted) { 1991.21Smycroft diskboot = (strcasecmp(b->protocol, "SCSI") == 0) || 2001.29Smhitch (strcasecmp(b->protocol, "RAID") == 0) || 2011.29Smhitch (strcasecmp(b->protocol, "I2O") == 0) || 2021.21Smycroft (strcasecmp(b->protocol, "IDE") == 0); 2031.21Smycroft netboot = (strcasecmp(b->protocol, "BOOTP") == 0) || 2041.21Smycroft (strcasecmp(b->protocol, "MOP") == 0); 2051.21Smycroft DR_VERBOSE(printf("diskboot = %d, netboot = %d\n", diskboot, 2061.21Smycroft netboot)); 2071.1Sross initted = 1; 2081.1Sross } 2091.21Smycroft 2101.1Sross if (primarydev == NULL) { 2111.24Sthorpej if (!device_is_a(dev, "tsp")) 2121.1Sross return; 2131.1Sross else { 2141.1Sross struct tsp_attach_args *tsp = aux; 2151.1Sross 2161.1Sross if (b->bus != tsp->tsp_slot) 2171.1Sross return; 2181.1Sross primarydev = dev; 2191.1Sross DR_VERBOSE(printf("\nprimarydev = %s\n", 2201.21Smycroft dev->dv_xname)); 2211.1Sross return; 2221.1Sross } 2231.1Sross } 2241.21Smycroft 2251.1Sross if (pcidev == NULL) { 2261.24Sthorpej if (!device_is_a(dev, "pci")) 2271.1Sross return; 2281.21Smycroft /* 2291.21Smycroft * Try to find primarydev anywhere in the ancestry. This is 2301.21Smycroft * necessary if the PCI bus is hidden behind a bridge. 2311.21Smycroft */ 2321.21Smycroft while (parent) { 2331.21Smycroft if (parent == primarydev) 2341.21Smycroft break; 2351.23Sthorpej parent = device_parent(parent); 2361.21Smycroft } 2371.21Smycroft if (!parent) 2381.1Sross return; 2391.1Sross else { 2401.1Sross struct pcibus_attach_args *pba = aux; 2411.1Sross 2421.1Sross if ((b->slot / 1000) != pba->pba_bus) 2431.1Sross return; 2441.1Sross 2451.1Sross pcidev = dev; 2461.21Smycroft DR_VERBOSE(printf("\npcidev = %s\n", dev->dv_xname)); 2471.1Sross return; 2481.1Sross } 2491.1Sross } 2501.21Smycroft 2511.21Smycroft if (ctrlrdev == NULL) { 2521.1Sross if (parent != pcidev) 2531.1Sross return; 2541.1Sross else { 2551.1Sross struct pci_attach_args *pa = aux; 2561.21Smycroft int slot; 2571.1Sross 2581.21Smycroft slot = pa->pa_bus * 1000 + pa->pa_function * 100 + 2591.21Smycroft pa->pa_device; 2601.21Smycroft if (b->slot != slot) 2611.1Sross return; 2621.1Sross 2631.21Smycroft if (netboot) { 2641.21Smycroft booted_device = dev; 2651.21Smycroft DR_VERBOSE(printf("\nbooted_device = %s\n", 2661.21Smycroft dev->dv_xname)); 2671.21Smycroft found = 1; 2681.21Smycroft } else { 2691.21Smycroft ctrlrdev = dev; 2701.21Smycroft DR_VERBOSE(printf("\nctrlrdev = %s\n", 2711.21Smycroft dev->dv_xname)); 2721.21Smycroft } 2731.1Sross return; 2741.1Sross } 2751.1Sross } 2761.21Smycroft 2771.21Smycroft if (!diskboot) 2781.21Smycroft return; 2791.21Smycroft 2801.24Sthorpej if (device_is_a(dev, "sd") || 2811.24Sthorpej device_is_a(dev, "st") || 2821.24Sthorpej device_is_a(dev, "cd")) { 2831.1Sross struct scsipibus_attach_args *sa = aux; 2841.21Smycroft struct scsipi_periph *periph = sa->sa_periph; 2851.21Smycroft int unit; 2861.1Sross 2871.23Sthorpej if (device_parent(parent) != ctrlrdev) 2881.1Sross return; 2891.1Sross 2901.21Smycroft unit = periph->periph_target * 100 + periph->periph_lun; 2911.21Smycroft if (b->unit != unit) 2921.1Sross return; 2931.21Smycroft if (b->channel != periph->periph_channel->chan_channel) 2941.1Sross return; 2951.1Sross 2961.1Sross /* we've found it! */ 2971.1Sross booted_device = dev; 2981.21Smycroft DR_VERBOSE(printf("\nbooted_device = %s\n", dev->dv_xname)); 2991.1Sross found = 1; 3001.1Sross } 3011.1Sross 3021.29Smhitch if (device_is_a(dev, "ld") && device_is_a(parent, "iop")) { 3031.29Smhitch /* 3041.29Smhitch * Argh! The attach arguments for ld devices is not 3051.29Smhitch * consistent, so each supported raid controller requires 3061.29Smhitch * different checks. 3071.29Smhitch */ 3081.29Smhitch struct iop_attach_args *iopa = aux; 3091.29Smhitch 3101.29Smhitch if (parent != ctrlrdev) 3111.29Smhitch return; 3121.29Smhitch 3131.29Smhitch if (b->unit != iopa->ia_tid) 3141.29Smhitch return; 3151.29Smhitch /* we've found it! */ 3161.29Smhitch booted_device = dev; 3171.29Smhitch DR_VERBOSE(printf("\nbooted_device = %s\n", dev->dv_xname)); 3181.29Smhitch found = 1; 3191.29Smhitch } 3201.29Smhitch 3211.29Smhitch if (device_is_a(dev, "ld") && device_is_a(parent, "mlx")) { 3221.29Smhitch /* 3231.29Smhitch * Argh! The attach arguments for ld devices is not 3241.29Smhitch * consistent, so each supported raid controller requires 3251.29Smhitch * different checks. 3261.29Smhitch */ 3271.29Smhitch struct mlx_attach_args *mlxa = aux; 3281.29Smhitch 3291.29Smhitch if (parent != ctrlrdev) 3301.29Smhitch return; 3311.29Smhitch 3321.29Smhitch if (b->unit != mlxa->mlxa_unit) 3331.29Smhitch return; 3341.29Smhitch /* we've found it! */ 3351.29Smhitch booted_device = dev; 3361.29Smhitch DR_VERBOSE(printf("\nbooted_device = %s\n", dev->dv_xname)); 3371.29Smhitch found = 1; 3381.29Smhitch } 3391.29Smhitch 3401.1Sross /* 3411.1Sross * Support to boot from IDE drives. 3421.1Sross */ 3431.24Sthorpej if (device_is_a(dev, "wd")) { 3441.13Sbouyer struct ata_device *adev = aux; 3451.21Smycroft 3461.24Sthorpej if (!device_is_a(parent, "atabus")) 3471.1Sross return; 3481.23Sthorpej if (device_parent(parent) != ctrlrdev) 3491.21Smycroft return; 3501.21Smycroft 3511.3Sveego DR_VERBOSE(printf("\nAtapi info: drive: %d, channel %d\n", 3521.13Sbouyer adev->adev_drv_data->drive, adev->adev_channel)); 3531.3Sveego DR_VERBOSE(printf("Bootdev info: unit: %d, channel: %d\n", 3541.3Sveego b->unit, b->channel)); 3551.13Sbouyer if (b->unit != adev->adev_drv_data->drive || 3561.13Sbouyer b->channel != adev->adev_channel) 3571.3Sveego return; 3581.1Sross 3591.1Sross /* we've found it! */ 3601.1Sross booted_device = dev; 3611.21Smycroft DR_VERBOSE(printf("booted_device = %s\n", dev->dv_xname)); 3621.1Sross found = 1; 3631.1Sross } 3641.1Sross} 365