dec_6600.c revision 1.16
1/* $NetBSD: dec_6600.c,v 1.16 2002/09/27 02:24:08 thorpej 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#include "opt_kgdb.h" 31 32#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 33 34__KERNEL_RCSID(0, "$NetBSD: dec_6600.c,v 1.16 2002/09/27 02:24:08 thorpej Exp $"); 35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/device.h> 39#include <sys/termios.h> 40#include <sys/conf.h> 41#include <dev/cons.h> 42 43#include <machine/rpb.h> 44#include <machine/autoconf.h> 45#include <machine/cpuconf.h> 46#include <machine/bus.h> 47 48#include <dev/ic/comreg.h> 49#include <dev/ic/comvar.h> 50 51#include <dev/isa/isareg.h> 52#include <dev/isa/isavar.h> 53#include <dev/ic/i8042reg.h> 54#include <dev/ic/pckbcvar.h> 55#include <dev/pci/pcireg.h> 56#include <dev/pci/pcivar.h> 57 58#include <alpha/pci/tsreg.h> 59#include <alpha/pci/tsvar.h> 60 61#include <dev/scsipi/scsi_all.h> 62#include <dev/scsipi/scsipi_all.h> 63#include <dev/scsipi/scsiconf.h> 64#include <dev/ata/atavar.h> 65#include <dev/ata/wdvar.h> 66 67#include "pckbd.h" 68 69#ifndef CONSPEED 70#define CONSPEED TTYDEF_SPEED 71#endif 72 73#define DR_VERBOSE(f) while (0) 74 75static int comcnrate __attribute__((unused)) = CONSPEED; 76 77void dec_6600_init __P((void)); 78static void dec_6600_cons_init __P((void)); 79static void dec_6600_device_register __P((struct device *, void *)); 80 81#ifdef KGDB 82#include <machine/db_machdep.h> 83 84static const char *kgdb_devlist[] = { 85 "com", 86 NULL, 87}; 88#endif /* KGDB */ 89 90void 91dec_6600_init() 92{ 93 94 platform.family = "6600"; 95 96 if ((platform.model = alpha_dsr_sysname()) == NULL) { 97 /* XXX Don't know the system variations, yet. */ 98 platform.model = alpha_unknown_sysname(); 99 } 100 101 platform.iobus = "tsc"; 102 platform.cons_init = dec_6600_cons_init; 103 platform.device_register = dec_6600_device_register; 104 STQP(TS_C_DIM0) = 0UL; 105 STQP(TS_C_DIM1) = 0UL; 106} 107 108static void 109dec_6600_cons_init() 110{ 111 struct ctb *ctb; 112 u_int64_t ctbslot; 113 struct tsp_config *tsp; 114 115 ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off); 116 ctbslot = ctb->ctb_turboslot; 117 118 /* Console hose defaults to hose 0. */ 119 tsp_console_hose = 0; 120 121 tsp = tsp_init(0, tsp_console_hose); 122 123 switch (ctb->ctb_term_type) { 124 case CTB_PRINTERPORT: 125 /* serial console ... */ 126 assert(CTB_TURBOSLOT_HOSE(ctbslot) == 0); 127 /* XXX */ 128 { 129 /* 130 * Delay to allow PROM putchars to complete. 131 * FIFO depth * character time, 132 * character time = (1000000 / (defaultrate / 10)) 133 */ 134 DELAY(160000000 / comcnrate); 135 136 if(comcnattach(&tsp->pc_iot, 0x3f8, comcnrate, 137 COM_FREQ, 138 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8)) 139 panic("can't init serial console"); 140 141 break; 142 } 143 144 case CTB_GRAPHICS: 145#if NPCKBD > 0 146 /* display console ... */ 147 /* XXX */ 148 (void) pckbc_cnattach(&tsp->pc_iot, IO_KBD, KBCMDP, 149 PCKBC_KBD_SLOT); 150 151 if (CTB_TURBOSLOT_TYPE(ctbslot) == 152 CTB_TURBOSLOT_TYPE_ISA) 153 isa_display_console(&tsp->pc_iot, &tsp->pc_memt); 154 else { 155 /* The display PCI might be different */ 156 tsp_console_hose = CTB_TURBOSLOT_HOSE(ctbslot); 157 tsp = tsp_init(0, tsp_console_hose); 158 pci_display_console(&tsp->pc_iot, &tsp->pc_memt, 159 &tsp->pc_pc, CTB_TURBOSLOT_BUS(ctbslot), 160 CTB_TURBOSLOT_SLOT(ctbslot), 0); 161 } 162#else 163 panic("not configured to use display && keyboard console"); 164#endif 165 break; 166 167 default: 168 printf("ctb_term_type = 0x%lx ctb_turboslot = 0x%lx" 169 " hose = %ld\n", ctb->ctb_term_type, ctbslot, 170 CTB_TURBOSLOT_HOSE(ctbslot)); 171 172 panic("consinit: unknown console type %ld\n", 173 ctb->ctb_term_type); 174 } 175#ifdef KGDB 176 /* Attach the KGDB device. */ 177 alpha_kgdb_init(kgdb_devlist, &tsp->pc_iot); 178#endif /* KGDB */ 179} 180 181static void 182dec_6600_device_register(dev, aux) 183 struct device *dev; 184 void *aux; 185{ 186 static int found, initted, scsiboot, ideboot, netboot; 187 static struct device *primarydev, *pcidev, *scsipidev; 188 struct bootdev_data *b = bootdev_data; 189 struct device *parent = dev->dv_parent; 190 struct cfdata *cf = dev->dv_cfdata; 191 const char *name = cf->cf_name; 192 193 if (found) 194 return; 195 196 if (!initted) { 197 scsiboot = (strcmp(b->protocol, "SCSI") == 0); 198 netboot = (strcmp(b->protocol, "BOOTP") == 0) || 199 (strcmp(b->protocol, "MOP") == 0); 200 /* 201 * Add an extra check to boot from ide drives: 202 * Newer SRM firmware use the protocol identifier IDE, 203 * older SRM firmware use the protocol identifier SCSI. 204 */ 205 ideboot = (strcmp(b->protocol, "IDE") == 0); 206 DR_VERBOSE(printf("scsiboot = %d, ideboot = %d, netboot = %d\n", 207 scsiboot, ideboot, netboot)); 208 initted = 1; 209 } 210 if (primarydev == NULL) { 211 if (strcmp(name, "tsp")) 212 return; 213 else { 214 struct tsp_attach_args *tsp = aux; 215 216 if (b->bus != tsp->tsp_slot) 217 return; 218 primarydev = dev; 219 DR_VERBOSE(printf("\nprimarydev = %s\n", 220 primarydev->dv_xname)); 221 return; 222 } 223 } 224 if (pcidev == NULL) { 225 if (parent != primarydev) 226 return; 227 if (strcmp(name, "pci")) 228 return; 229 else { 230 struct pcibus_attach_args *pba = aux; 231 232 if ((b->slot / 1000) != pba->pba_bus) 233 return; 234 235 pcidev = dev; 236 DR_VERBOSE(printf("\npcidev = %s\n", 237 pcidev->dv_xname)); 238 return; 239 } 240 } 241 if ((ideboot || scsiboot) && (scsipidev == NULL)) { 242 if (parent != pcidev) 243 return; 244 else { 245 struct pci_attach_args *pa = aux; 246 247 if (b->slot % 1000 / 100 != pa->pa_function) 248 return; 249 if (b->slot % 100 != pa->pa_device) 250 return; 251 252 scsipidev = dev; 253 DR_VERBOSE(printf("\nscsipidev = %s\n", 254 scsipidev->dv_xname)); 255 return; 256 } 257 } 258 if ((ideboot || scsiboot) && 259 (!strcmp(name, "sd") || 260 !strcmp(name, "st") || 261 !strcmp(name, "cd"))) { 262 struct scsipibus_attach_args *sa = aux; 263 264 if (parent->dv_parent != scsipidev) 265 return; 266 267 if ((sa->sa_periph->periph_channel->chan_bustype->bustype_type 268 == SCSIPI_BUSTYPE_SCSI || 269 sa->sa_periph->periph_channel->chan_bustype->bustype_type 270 == SCSIPI_BUSTYPE_ATAPI) 271 && b->unit / 100 != sa->sa_periph->periph_target) 272 return; 273 274 /* XXX LUN! */ 275 276 switch (b->boot_dev_type) { 277 case 0: 278 if (strcmp(name, "sd") && 279 strcmp(name, "cd")) 280 return; 281 break; 282 case 1: 283 if (strcmp(name, "st")) 284 return; 285 break; 286 default: 287 return; 288 } 289 290 /* we've found it! */ 291 booted_device = dev; 292 DR_VERBOSE(printf("\nbooted_device = %s\n", 293 booted_device->dv_xname)); 294 found = 1; 295 } 296 297 /* 298 * Support to boot from IDE drives. 299 */ 300 if ((ideboot || scsiboot) && !strcmp(name, "wd")) { 301 struct ata_device *adev = aux; 302 if ((strncmp("pciide", parent->dv_xname, 6) != 0)) { 303 return; 304 } else { 305 if (parent != scsipidev) 306 return; 307 } 308 DR_VERBOSE(printf("\nAtapi info: drive: %d, channel %d\n", 309 adev->adev_drv_data->drive, adev->adev_channel)); 310 DR_VERBOSE(printf("Bootdev info: unit: %d, channel: %d\n", 311 b->unit, b->channel)); 312 if (b->unit != adev->adev_drv_data->drive || 313 b->channel != adev->adev_channel) 314 return; 315 316 /* we've found it! */ 317 booted_device = dev; 318 DR_VERBOSE(printf("booted_device = %s\n", 319 booted_device->dv_xname)); 320 found = 1; 321 } 322 if (netboot) { 323 if (parent != pcidev) 324 return; 325 else { 326 struct pci_attach_args *pa = aux; 327 328 if (b->slot % 1000 / 100 != pa->pa_function) 329 return; 330 if ((b->slot % 100) != pa->pa_device) 331 return; 332 333 booted_device = dev; 334 DR_VERBOSE(printf("\nbooted_device = %s\n", 335 booted_device->dv_xname)); 336 found = 1; 337 return; 338 } 339 } 340} 341