1 /* $NetBSD: dec_1000a.c,v 1.18 2002/09/27 15:35:33 provos Exp $ */ 2 3 /* 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is based on dec_kn20aa.c, written by Chris G. Demetriou at 8 * Carnegie-Mellon University. Platform support for Noritake, Pintake, and 9 * Corelle by Ross Harvey with copyright assignment by permission of Avalon 10 * Computer Systems, Inc. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the NetBSD 23 * Foundation, Inc. and its contributors. 24 * 4. Neither the name of The NetBSD Foundation nor the names of its 25 * contributors may be used to endorse or promote products derived 26 * from this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 */ 40 41 /* 42 * Copyright (c) 1995, 1996, 1997 Carnegie-Mellon University. 43 * All rights reserved. 44 * 45 * Author: Chris G. Demetriou 46 * 47 * Permission to use, copy, modify and distribute this software and 48 * its documentation is hereby granted, provided that both the copyright 49 * notice and this permission notice appear in all copies of the 50 * software, derivative works or modified versions, and any portions 51 * thereof, and that both notices appear in supporting documentation. 52 * 53 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 54 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 55 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 56 * 57 * Carnegie Mellon requests users of this software to return to 58 * 59 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 60 * School of Computer Science 61 * Carnegie Mellon University 62 * Pittsburgh PA 15213-3890 63 * 64 * any improvements or extensions that they make and grant Carnegie the 65 * rights to redistribute these changes. 66 */ 67 /* 68 * Additional Copyright (c) 1997 by Matthew Jacob for NASA/Ames Research Center 69 */ 70 71 #include "opt_kgdb.h" 72 73 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 74 75 __KERNEL_RCSID(0, "$NetBSD: dec_1000a.c,v 1.18 2002/09/27 15:35:33 provos Exp $"); 76 77 #include <sys/param.h> 78 #include <sys/systm.h> 79 #include <sys/device.h> 80 #include <sys/termios.h> 81 #include <sys/conf.h> 82 #include <dev/cons.h> 83 84 #include <machine/rpb.h> 85 #include <machine/autoconf.h> 86 #include <machine/cpuconf.h> 87 #include <machine/bus.h> 88 89 #include <dev/ic/comreg.h> 90 #include <dev/ic/comvar.h> 91 92 #include <dev/isa/isareg.h> 93 #include <dev/isa/isavar.h> 94 #include <dev/ic/i8042reg.h> 95 #include <dev/ic/pckbcvar.h> 96 #include <dev/pci/pcireg.h> 97 #include <dev/pci/pcivar.h> 98 99 #include <alpha/pci/apecsreg.h> 100 #include <alpha/pci/apecsvar.h> 101 #include <alpha/pci/ciareg.h> 102 #include <alpha/pci/ciavar.h> 103 104 #include <dev/scsipi/scsi_all.h> 105 #include <dev/scsipi/scsipi_all.h> 106 #include <dev/scsipi/scsiconf.h> 107 108 #include "pckbd.h" 109 110 #ifndef CONSPEED 111 #define CONSPEED TTYDEF_SPEED 112 #endif 113 static int comcnrate = CONSPEED; 114 115 void _dec_1000a_init __P((void)); 116 static void dec_1000a_cons_init __P((void)); 117 static void dec_1000a_device_register __P((struct device *, void *)); 118 119 #ifdef KGDB 120 #include <machine/db_machdep.h> 121 122 static const char *kgdb_devlist[] = { 123 "com", 124 NULL, 125 }; 126 #endif /* KGDB */ 127 128 static const struct alpha_variation_table dec_1000_variations[] = { 129 { 0, "AlphaServer 1000" }, 130 { 0, NULL }, 131 }; 132 133 static const struct alpha_variation_table dec_1000a_variations[] = { 134 { 0, "AlphaServer 1000A" }, 135 { 0, NULL }, 136 }; 137 138 void 139 _dec_1000a_init() 140 { 141 u_int64_t variation; 142 143 platform.family = "AlphaServer 1000/1000A"; 144 145 if ((platform.model = alpha_dsr_sysname()) == NULL) { 146 variation = hwrpb->rpb_variation & SV_ST_MASK; 147 if ((platform.model = alpha_variation_name(variation, 148 cputype == ST_DEC_1000 ? dec_1000_variations 149 : dec_1000a_variations)) == NULL) 150 platform.model = alpha_unknown_sysname(); 151 } 152 153 switch(PCS_CPU_MAJORTYPE(LOCATE_PCS(hwrpb, 0))) { 154 case PCS_PROC_EV4: 155 case PCS_PROC_EV45: 156 platform.iobus = "apecs"; 157 break; 158 default: 159 platform.iobus = "cia"; 160 break; 161 } 162 platform.cons_init = dec_1000a_cons_init; 163 platform.device_register = dec_1000a_device_register; 164 } 165 166 static void 167 dec_1000a_cons_init() 168 { 169 struct ctb *ctb; 170 struct cia_config *ccp; 171 struct apecs_config *acp; 172 extern struct cia_config cia_configuration; 173 extern struct apecs_config apecs_configuration; 174 bus_space_tag_t iot, memt; 175 struct alpha_pci_chipset *pcichipset; 176 177 if(strcmp(platform.iobus, "cia") == 0) { 178 ccp = &cia_configuration; 179 cia_init(ccp, 0); 180 iot = &ccp->cc_iot; 181 memt = &ccp->cc_memt; 182 pcichipset = &ccp->cc_pc; 183 } else { 184 acp = &apecs_configuration; 185 apecs_init(acp, 0); 186 iot = &acp->ac_iot; 187 memt = &acp->ac_memt; 188 pcichipset = &acp->ac_pc; 189 } 190 191 ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off); 192 193 switch (ctb->ctb_term_type) { 194 case CTB_PRINTERPORT: 195 /* serial console ... */ 196 /* XXX */ 197 { 198 /* 199 * Delay to allow PROM putchars to complete. 200 * FIFO depth * character time, 201 * character time = (1000000 / (defaultrate / 10)) 202 */ 203 DELAY(160000000 / comcnrate); 204 205 if(comcnattach(iot, 0x3f8, comcnrate, 206 COM_FREQ, 207 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8)) 208 panic("can't init serial console"); 209 210 break; 211 } 212 213 case CTB_GRAPHICS: 214 #if NPCKBD > 0 215 /* display console ... */ 216 /* XXX */ 217 (void) pckbc_cnattach(iot, IO_KBD, KBCMDP, PCKBC_KBD_SLOT); 218 219 /* 220 * AlphaServer 1000s have a firmware bug whereby the 221 * built-in ISA VGA is reported incorrectly -- ctb_turboslot 222 * is mostly 0. 223 */ 224 switch (CTB_TURBOSLOT_TYPE(ctb->ctb_turboslot)) { 225 case CTB_TURBOSLOT_TYPE_PCI: 226 pci_display_console(iot, memt, pcichipset, 227 CTB_TURBOSLOT_BUS(ctb->ctb_turboslot), 228 CTB_TURBOSLOT_SLOT(ctb->ctb_turboslot), 0); 229 break; 230 231 default: 232 isa_display_console(iot, memt); 233 break; 234 } 235 #else 236 panic("not configured to use display && keyboard console"); 237 #endif 238 break; 239 240 default: 241 printf("ctb->ctb_term_type = 0x%lx\n", ctb->ctb_term_type); 242 printf("ctb->ctb_turboslot = 0x%lx\n", ctb->ctb_turboslot); 243 244 panic("consinit: unknown console type %ld", 245 ctb->ctb_term_type); 246 } 247 #ifdef KGDB 248 /* Attach the KGDB device. */ 249 alpha_kgdb_init(kgdb_devlist, iot); 250 #endif /* KGDB */ 251 } 252 253 static void 254 dec_1000a_device_register(dev, aux) 255 struct device *dev; 256 void *aux; 257 { 258 static int found, initted, scsiboot, netboot; 259 static struct device *pcidev, *scsidev; 260 struct bootdev_data *b = bootdev_data; 261 struct device *parent = dev->dv_parent; 262 struct cfdata *cf = dev->dv_cfdata; 263 const char *name = cf->cf_name; 264 265 if (found) 266 return; 267 268 if (!initted) { 269 scsiboot = (strcmp(b->protocol, "SCSI") == 0); 270 netboot = (strcmp(b->protocol, "BOOTP") == 0) || 271 (strcmp(b->protocol, "MOP") == 0); 272 #if 0 273 printf("scsiboot = %d, netboot = %d\n", scsiboot, netboot); 274 #endif 275 initted =1; 276 } 277 278 if (pcidev == NULL) { 279 if (strcmp(name, "pci")) 280 return; 281 else { 282 struct pcibus_attach_args *pba = aux; 283 284 if ((b->slot / 1000) != pba->pba_bus) 285 return; 286 287 pcidev = dev; 288 #if 0 289 printf("\npcidev = %s\n", pcidev->dv_xname); 290 #endif 291 return; 292 } 293 } 294 295 if (scsiboot && (scsidev == NULL)) { 296 if (parent != pcidev) 297 return; 298 else { 299 struct pci_attach_args *pa = aux; 300 301 if ((b->slot % 1000) != pa->pa_device) 302 return; 303 304 /* XXX function? */ 305 306 scsidev = dev; 307 #if 0 308 printf("\nscsidev = %s\n", scsidev->dv_xname); 309 #endif 310 return; 311 } 312 } 313 314 if (scsiboot && 315 (!strcmp(name, "sd") || 316 !strcmp(name, "st") || 317 !strcmp(name, "cd"))) { 318 struct scsipibus_attach_args *sa = aux; 319 320 if (parent->dv_parent != scsidev) 321 return; 322 323 if (b->unit / 100 != sa->sa_periph->periph_target) 324 return; 325 326 /* XXX LUN! */ 327 328 switch (b->boot_dev_type) { 329 case 0: 330 if (strcmp(name, "sd") && 331 strcmp(name, "cd")) 332 return; 333 break; 334 case 1: 335 if (strcmp(name, "st")) 336 return; 337 break; 338 default: 339 return; 340 } 341 342 /* we've found it! */ 343 booted_device = dev; 344 #if 0 345 printf("\nbooted_device = %s\n", booted_device->dv_xname); 346 #endif 347 found = 1; 348 } 349 350 if (netboot) { 351 if (parent != pcidev) 352 return; 353 else { 354 struct pci_attach_args *pa = aux; 355 356 if ((b->slot % 1000) != pa->pa_device) 357 return; 358 359 /* XXX function? */ 360 361 booted_device = dev; 362 #if 0 363 printf("\nbooted_device = %s\n", booted_device->dv_xname); 364 #endif 365 found = 1; 366 return; 367 } 368 } 369 } 370