dec_6600.c revision 1.29
1/* $NetBSD: dec_6600.c,v 1.29 2009/09/14 02:46:29 mhitch 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.29 2009/09/14 02:46:29 mhitch 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 66#include <dev/ic/mlxio.h> 67#include <dev/ic/mlxvar.h> 68 69#include <dev/i2o/i2o.h> 70#include <dev/i2o/iopio.h> 71#include <dev/i2o/iopvar.h> 72 73#include "pckbd.h" 74 75#ifndef CONSPEED 76#define CONSPEED TTYDEF_SPEED 77#endif 78 79#define DR_VERBOSE(f) while (0) 80 81static int comcnrate __attribute__((unused)) = CONSPEED; 82 83void dec_6600_init(void); 84static void dec_6600_cons_init(void); 85static void dec_6600_device_register(struct device *, void *); 86 87#ifdef KGDB 88#include <machine/db_machdep.h> 89 90static const char *kgdb_devlist[] = { 91 "com", 92 NULL, 93}; 94#endif /* KGDB */ 95 96void 97dec_6600_init() 98{ 99 100 platform.family = "6600"; 101 102 if ((platform.model = alpha_dsr_sysname()) == NULL) { 103 /* XXX Don't know the system variations, yet. */ 104 platform.model = alpha_unknown_sysname(); 105 } 106 107 platform.iobus = "tsc"; 108 platform.cons_init = dec_6600_cons_init; 109 platform.device_register = dec_6600_device_register; 110 STQP(TS_C_DIM0) = 0UL; 111 STQP(TS_C_DIM1) = 0UL; 112} 113 114static void 115dec_6600_cons_init() 116{ 117 struct ctb *ctb; 118 u_int64_t ctbslot; 119 struct tsp_config *tsp; 120 121 ctb = (struct ctb *)(((char *)hwrpb) + hwrpb->rpb_ctb_off); 122 ctbslot = ctb->ctb_turboslot; 123 124 /* Console hose defaults to hose 0. */ 125 tsp_console_hose = 0; 126 127 tsp = tsp_init(0, tsp_console_hose); 128 129 switch (ctb->ctb_term_type) { 130 case CTB_PRINTERPORT: 131 /* serial console ... */ 132 assert(CTB_TURBOSLOT_HOSE(ctbslot) == 0); 133 /* XXX */ 134 { 135 /* 136 * Delay to allow PROM putchars to complete. 137 * FIFO depth * character time, 138 * character time = (1000000 / (defaultrate / 10)) 139 */ 140 DELAY(160000000 / comcnrate); 141 142 if(comcnattach(&tsp->pc_iot, 0x3f8, comcnrate, 143 COM_FREQ, COM_TYPE_NORMAL, 144 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8)) 145 panic("can't init serial console"); 146 147 break; 148 } 149 150 case CTB_GRAPHICS: 151#if NPCKBD > 0 152 /* display console ... */ 153 /* XXX */ 154 (void) pckbc_cnattach(&tsp->pc_iot, IO_KBD, KBCMDP, 155 PCKBC_KBD_SLOT); 156 157 if (CTB_TURBOSLOT_TYPE(ctbslot) == 158 CTB_TURBOSLOT_TYPE_ISA) 159 isa_display_console(&tsp->pc_iot, &tsp->pc_memt); 160 else { 161 /* The display PCI might be different */ 162 tsp_console_hose = CTB_TURBOSLOT_HOSE(ctbslot); 163 tsp = tsp_init(0, tsp_console_hose); 164 pci_display_console(&tsp->pc_iot, &tsp->pc_memt, 165 &tsp->pc_pc, CTB_TURBOSLOT_BUS(ctbslot), 166 CTB_TURBOSLOT_SLOT(ctbslot), 0); 167 } 168#else 169 panic("not configured to use display && keyboard console"); 170#endif 171 break; 172 173 default: 174 printf("ctb_term_type = 0x%lx ctb_turboslot = 0x%lx" 175 " hose = %ld\n", ctb->ctb_term_type, ctbslot, 176 CTB_TURBOSLOT_HOSE(ctbslot)); 177 178 panic("consinit: unknown console type %ld", 179 ctb->ctb_term_type); 180 } 181#ifdef KGDB 182 /* Attach the KGDB device. */ 183 alpha_kgdb_init(kgdb_devlist, &tsp->pc_iot); 184#endif /* KGDB */ 185} 186 187static void 188dec_6600_device_register(struct device *dev, void *aux) 189{ 190 static int found, initted, diskboot, netboot; 191 static struct device *primarydev, *pcidev, *ctrlrdev; 192 struct bootdev_data *b = bootdev_data; 193 struct device *parent = device_parent(dev); 194 195 if (found) 196 return; 197 198 if (!initted) { 199 diskboot = (strcasecmp(b->protocol, "SCSI") == 0) || 200 (strcasecmp(b->protocol, "RAID") == 0) || 201 (strcasecmp(b->protocol, "I2O") == 0) || 202 (strcasecmp(b->protocol, "IDE") == 0); 203 netboot = (strcasecmp(b->protocol, "BOOTP") == 0) || 204 (strcasecmp(b->protocol, "MOP") == 0); 205 DR_VERBOSE(printf("diskboot = %d, netboot = %d\n", diskboot, 206 netboot)); 207 initted = 1; 208 } 209 210 if (primarydev == NULL) { 211 if (!device_is_a(dev, "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 dev->dv_xname)); 221 return; 222 } 223 } 224 225 if (pcidev == NULL) { 226 if (!device_is_a(dev, "pci")) 227 return; 228 /* 229 * Try to find primarydev anywhere in the ancestry. This is 230 * necessary if the PCI bus is hidden behind a bridge. 231 */ 232 while (parent) { 233 if (parent == primarydev) 234 break; 235 parent = device_parent(parent); 236 } 237 if (!parent) 238 return; 239 else { 240 struct pcibus_attach_args *pba = aux; 241 242 if ((b->slot / 1000) != pba->pba_bus) 243 return; 244 245 pcidev = dev; 246 DR_VERBOSE(printf("\npcidev = %s\n", dev->dv_xname)); 247 return; 248 } 249 } 250 251 if (ctrlrdev == NULL) { 252 if (parent != pcidev) 253 return; 254 else { 255 struct pci_attach_args *pa = aux; 256 int slot; 257 258 slot = pa->pa_bus * 1000 + pa->pa_function * 100 + 259 pa->pa_device; 260 if (b->slot != slot) 261 return; 262 263 if (netboot) { 264 booted_device = dev; 265 DR_VERBOSE(printf("\nbooted_device = %s\n", 266 dev->dv_xname)); 267 found = 1; 268 } else { 269 ctrlrdev = dev; 270 DR_VERBOSE(printf("\nctrlrdev = %s\n", 271 dev->dv_xname)); 272 } 273 return; 274 } 275 } 276 277 if (!diskboot) 278 return; 279 280 if (device_is_a(dev, "sd") || 281 device_is_a(dev, "st") || 282 device_is_a(dev, "cd")) { 283 struct scsipibus_attach_args *sa = aux; 284 struct scsipi_periph *periph = sa->sa_periph; 285 int unit; 286 287 if (device_parent(parent) != ctrlrdev) 288 return; 289 290 unit = periph->periph_target * 100 + periph->periph_lun; 291 if (b->unit != unit) 292 return; 293 if (b->channel != periph->periph_channel->chan_channel) 294 return; 295 296 /* we've found it! */ 297 booted_device = dev; 298 DR_VERBOSE(printf("\nbooted_device = %s\n", dev->dv_xname)); 299 found = 1; 300 } 301 302 if (device_is_a(dev, "ld") && device_is_a(parent, "iop")) { 303 /* 304 * Argh! The attach arguments for ld devices is not 305 * consistent, so each supported raid controller requires 306 * different checks. 307 */ 308 struct iop_attach_args *iopa = aux; 309 310 if (parent != ctrlrdev) 311 return; 312 313 if (b->unit != iopa->ia_tid) 314 return; 315 /* we've found it! */ 316 booted_device = dev; 317 DR_VERBOSE(printf("\nbooted_device = %s\n", dev->dv_xname)); 318 found = 1; 319 } 320 321 if (device_is_a(dev, "ld") && device_is_a(parent, "mlx")) { 322 /* 323 * Argh! The attach arguments for ld devices is not 324 * consistent, so each supported raid controller requires 325 * different checks. 326 */ 327 struct mlx_attach_args *mlxa = aux; 328 329 if (parent != ctrlrdev) 330 return; 331 332 if (b->unit != mlxa->mlxa_unit) 333 return; 334 /* we've found it! */ 335 booted_device = dev; 336 DR_VERBOSE(printf("\nbooted_device = %s\n", dev->dv_xname)); 337 found = 1; 338 } 339 340 /* 341 * Support to boot from IDE drives. 342 */ 343 if (device_is_a(dev, "wd")) { 344 struct ata_device *adev = aux; 345 346 if (!device_is_a(parent, "atabus")) 347 return; 348 if (device_parent(parent) != ctrlrdev) 349 return; 350 351 DR_VERBOSE(printf("\nAtapi info: drive: %d, channel %d\n", 352 adev->adev_drv_data->drive, adev->adev_channel)); 353 DR_VERBOSE(printf("Bootdev info: unit: %d, channel: %d\n", 354 b->unit, b->channel)); 355 if (b->unit != adev->adev_drv_data->drive || 356 b->channel != adev->adev_channel) 357 return; 358 359 /* we've found it! */ 360 booted_device = dev; 361 DR_VERBOSE(printf("booted_device = %s\n", dev->dv_xname)); 362 found = 1; 363 } 364} 365