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