dec_6600.c revision 1.27
11.27Sdsl/* $NetBSD: dec_6600.c,v 1.27 2009/03/14 14:45:52 dsl 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.27Sdsl__KERNEL_RCSID(0, "$NetBSD: dec_6600.c,v 1.27 2009/03/14 14:45:52 dsl 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.1Sross#include "pckbd.h" 671.1Sross 681.1Sross#ifndef CONSPEED 691.1Sross#define CONSPEED TTYDEF_SPEED 701.1Sross#endif 711.1Sross 721.1Sross#define DR_VERBOSE(f) while (0) 731.1Sross 741.1Srossstatic int comcnrate __attribute__((unused)) = CONSPEED; 751.1Sross 761.27Sdslvoid dec_6600_init(void); 771.27Sdslstatic void dec_6600_cons_init(void); 781.27Sdslstatic void dec_6600_device_register(struct device *, void *); 791.1Sross 801.9Sthorpej#ifdef KGDB 811.9Sthorpej#include <machine/db_machdep.h> 821.9Sthorpej 831.9Sthorpejstatic const char *kgdb_devlist[] = { 841.9Sthorpej "com", 851.9Sthorpej NULL, 861.9Sthorpej}; 871.9Sthorpej#endif /* KGDB */ 881.9Sthorpej 891.1Srossvoid 901.1Srossdec_6600_init() 911.1Sross{ 921.1Sross 931.1Sross platform.family = "6600"; 941.1Sross 951.1Sross if ((platform.model = alpha_dsr_sysname()) == NULL) { 961.1Sross /* XXX Don't know the system variations, yet. */ 971.1Sross platform.model = alpha_unknown_sysname(); 981.1Sross } 991.1Sross 1001.1Sross platform.iobus = "tsc"; 1011.1Sross platform.cons_init = dec_6600_cons_init; 1021.1Sross platform.device_register = dec_6600_device_register; 1031.1Sross STQP(TS_C_DIM0) = 0UL; 1041.1Sross STQP(TS_C_DIM1) = 0UL; 1051.1Sross} 1061.1Sross 1071.1Srossstatic void 1081.1Srossdec_6600_cons_init() 1091.1Sross{ 1101.1Sross struct ctb *ctb; 1111.1Sross u_int64_t ctbslot; 1121.1Sross struct tsp_config *tsp; 1131.1Sross 1141.26Syamt ctb = (struct ctb *)(((char *)hwrpb) + hwrpb->rpb_ctb_off); 1151.1Sross ctbslot = ctb->ctb_turboslot; 1161.1Sross 1171.8Sthorpej /* Console hose defaults to hose 0. */ 1181.8Sthorpej tsp_console_hose = 0; 1191.8Sthorpej 1201.8Sthorpej tsp = tsp_init(0, tsp_console_hose); 1211.1Sross 1221.1Sross switch (ctb->ctb_term_type) { 1231.12Sthorpej case CTB_PRINTERPORT: 1241.1Sross /* serial console ... */ 1251.1Sross assert(CTB_TURBOSLOT_HOSE(ctbslot) == 0); 1261.1Sross /* XXX */ 1271.1Sross { 1281.1Sross /* 1291.1Sross * Delay to allow PROM putchars to complete. 1301.1Sross * FIFO depth * character time, 1311.1Sross * character time = (1000000 / (defaultrate / 10)) 1321.1Sross */ 1331.1Sross DELAY(160000000 / comcnrate); 1341.1Sross 1351.1Sross if(comcnattach(&tsp->pc_iot, 0x3f8, comcnrate, 1361.18Sthorpej COM_FREQ, COM_TYPE_NORMAL, 1371.1Sross (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8)) 1381.1Sross panic("can't init serial console"); 1391.1Sross 1401.1Sross break; 1411.1Sross } 1421.1Sross 1431.12Sthorpej case CTB_GRAPHICS: 1441.1Sross#if NPCKBD > 0 1451.1Sross /* display console ... */ 1461.1Sross /* XXX */ 1471.6Ssoda (void) pckbc_cnattach(&tsp->pc_iot, IO_KBD, KBCMDP, 1481.6Ssoda PCKBC_KBD_SLOT); 1491.1Sross 1501.1Sross if (CTB_TURBOSLOT_TYPE(ctbslot) == 1511.1Sross CTB_TURBOSLOT_TYPE_ISA) 1521.1Sross isa_display_console(&tsp->pc_iot, &tsp->pc_memt); 1531.1Sross else { 1541.1Sross /* The display PCI might be different */ 1551.8Sthorpej tsp_console_hose = CTB_TURBOSLOT_HOSE(ctbslot); 1561.8Sthorpej tsp = tsp_init(0, tsp_console_hose); 1571.1Sross pci_display_console(&tsp->pc_iot, &tsp->pc_memt, 1581.1Sross &tsp->pc_pc, CTB_TURBOSLOT_BUS(ctbslot), 1591.1Sross CTB_TURBOSLOT_SLOT(ctbslot), 0); 1601.1Sross } 1611.1Sross#else 1621.1Sross panic("not configured to use display && keyboard console"); 1631.1Sross#endif 1641.1Sross break; 1651.1Sross 1661.1Sross default: 1671.1Sross printf("ctb_term_type = 0x%lx ctb_turboslot = 0x%lx" 1681.1Sross " hose = %ld\n", ctb->ctb_term_type, ctbslot, 1691.1Sross CTB_TURBOSLOT_HOSE(ctbslot)); 1701.1Sross 1711.17Sprovos panic("consinit: unknown console type %ld", 1721.1Sross ctb->ctb_term_type); 1731.1Sross } 1741.9Sthorpej#ifdef KGDB 1751.9Sthorpej /* Attach the KGDB device. */ 1761.9Sthorpej alpha_kgdb_init(kgdb_devlist, &tsp->pc_iot); 1771.9Sthorpej#endif /* KGDB */ 1781.1Sross} 1791.1Sross 1801.1Srossstatic void 1811.1Srossdec_6600_device_register(dev, aux) 1821.1Sross struct device *dev; 1831.1Sross void *aux; 1841.1Sross{ 1851.21Smycroft static int found, initted, diskboot, netboot; 1861.21Smycroft static struct device *primarydev, *pcidev, *ctrlrdev; 1871.1Sross struct bootdev_data *b = bootdev_data; 1881.23Sthorpej struct device *parent = device_parent(dev); 1891.1Sross 1901.1Sross if (found) 1911.1Sross return; 1921.1Sross 1931.1Sross if (!initted) { 1941.21Smycroft diskboot = (strcasecmp(b->protocol, "SCSI") == 0) || 1951.21Smycroft (strcasecmp(b->protocol, "IDE") == 0); 1961.21Smycroft netboot = (strcasecmp(b->protocol, "BOOTP") == 0) || 1971.21Smycroft (strcasecmp(b->protocol, "MOP") == 0); 1981.21Smycroft DR_VERBOSE(printf("diskboot = %d, netboot = %d\n", diskboot, 1991.21Smycroft netboot)); 2001.1Sross initted = 1; 2011.1Sross } 2021.21Smycroft 2031.1Sross if (primarydev == NULL) { 2041.24Sthorpej if (!device_is_a(dev, "tsp")) 2051.1Sross return; 2061.1Sross else { 2071.1Sross struct tsp_attach_args *tsp = aux; 2081.1Sross 2091.1Sross if (b->bus != tsp->tsp_slot) 2101.1Sross return; 2111.1Sross primarydev = dev; 2121.1Sross DR_VERBOSE(printf("\nprimarydev = %s\n", 2131.21Smycroft dev->dv_xname)); 2141.1Sross return; 2151.1Sross } 2161.1Sross } 2171.21Smycroft 2181.1Sross if (pcidev == NULL) { 2191.24Sthorpej if (!device_is_a(dev, "pci")) 2201.1Sross return; 2211.21Smycroft /* 2221.21Smycroft * Try to find primarydev anywhere in the ancestry. This is 2231.21Smycroft * necessary if the PCI bus is hidden behind a bridge. 2241.21Smycroft */ 2251.21Smycroft while (parent) { 2261.21Smycroft if (parent == primarydev) 2271.21Smycroft break; 2281.23Sthorpej parent = device_parent(parent); 2291.21Smycroft } 2301.21Smycroft if (!parent) 2311.1Sross return; 2321.1Sross else { 2331.1Sross struct pcibus_attach_args *pba = aux; 2341.1Sross 2351.1Sross if ((b->slot / 1000) != pba->pba_bus) 2361.1Sross return; 2371.1Sross 2381.1Sross pcidev = dev; 2391.21Smycroft DR_VERBOSE(printf("\npcidev = %s\n", dev->dv_xname)); 2401.1Sross return; 2411.1Sross } 2421.1Sross } 2431.21Smycroft 2441.21Smycroft if (ctrlrdev == NULL) { 2451.1Sross if (parent != pcidev) 2461.1Sross return; 2471.1Sross else { 2481.1Sross struct pci_attach_args *pa = aux; 2491.21Smycroft int slot; 2501.1Sross 2511.21Smycroft slot = pa->pa_bus * 1000 + pa->pa_function * 100 + 2521.21Smycroft pa->pa_device; 2531.21Smycroft if (b->slot != slot) 2541.1Sross return; 2551.1Sross 2561.21Smycroft if (netboot) { 2571.21Smycroft booted_device = dev; 2581.21Smycroft DR_VERBOSE(printf("\nbooted_device = %s\n", 2591.21Smycroft dev->dv_xname)); 2601.21Smycroft found = 1; 2611.21Smycroft } else { 2621.21Smycroft ctrlrdev = dev; 2631.21Smycroft DR_VERBOSE(printf("\nctrlrdev = %s\n", 2641.21Smycroft dev->dv_xname)); 2651.21Smycroft } 2661.1Sross return; 2671.1Sross } 2681.1Sross } 2691.21Smycroft 2701.21Smycroft if (!diskboot) 2711.21Smycroft return; 2721.21Smycroft 2731.24Sthorpej if (device_is_a(dev, "sd") || 2741.24Sthorpej device_is_a(dev, "st") || 2751.24Sthorpej device_is_a(dev, "cd")) { 2761.1Sross struct scsipibus_attach_args *sa = aux; 2771.21Smycroft struct scsipi_periph *periph = sa->sa_periph; 2781.21Smycroft int unit; 2791.1Sross 2801.23Sthorpej if (device_parent(parent) != ctrlrdev) 2811.1Sross return; 2821.1Sross 2831.21Smycroft unit = periph->periph_target * 100 + periph->periph_lun; 2841.21Smycroft if (b->unit != unit) 2851.1Sross return; 2861.21Smycroft if (b->channel != periph->periph_channel->chan_channel) 2871.1Sross return; 2881.1Sross 2891.1Sross /* we've found it! */ 2901.1Sross booted_device = dev; 2911.21Smycroft DR_VERBOSE(printf("\nbooted_device = %s\n", dev->dv_xname)); 2921.1Sross found = 1; 2931.1Sross } 2941.1Sross 2951.1Sross /* 2961.1Sross * Support to boot from IDE drives. 2971.1Sross */ 2981.24Sthorpej if (device_is_a(dev, "wd")) { 2991.13Sbouyer struct ata_device *adev = aux; 3001.21Smycroft 3011.24Sthorpej if (!device_is_a(parent, "atabus")) 3021.1Sross return; 3031.23Sthorpej if (device_parent(parent) != ctrlrdev) 3041.21Smycroft return; 3051.21Smycroft 3061.3Sveego DR_VERBOSE(printf("\nAtapi info: drive: %d, channel %d\n", 3071.13Sbouyer adev->adev_drv_data->drive, adev->adev_channel)); 3081.3Sveego DR_VERBOSE(printf("Bootdev info: unit: %d, channel: %d\n", 3091.3Sveego b->unit, b->channel)); 3101.13Sbouyer if (b->unit != adev->adev_drv_data->drive || 3111.13Sbouyer b->channel != adev->adev_channel) 3121.3Sveego return; 3131.1Sross 3141.1Sross /* we've found it! */ 3151.1Sross booted_device = dev; 3161.21Smycroft DR_VERBOSE(printf("booted_device = %s\n", dev->dv_xname)); 3171.1Sross found = 1; 3181.1Sross } 3191.1Sross} 320