1 /* $NetBSD: dec_3000_500.c,v 1.33 2001/04/25 17:53:04 bouyer Exp $ */ 2 3 /* 4 * Copyright (c) 1994, 1995, 1996 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 <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 34 35 __KERNEL_RCSID(0, "$NetBSD: dec_3000_500.c,v 1.33 2001/04/25 17:53:04 bouyer Exp $"); 36 37 #include "opt_new_scc_driver.h" 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/device.h> 42 #include <sys/termios.h> 43 #include <dev/cons.h> 44 45 #include <machine/rpb.h> 46 #include <machine/autoconf.h> 47 #include <machine/conf.h> 48 49 #include <dev/tc/tcvar.h> 50 #include <dev/tc/tcdsvar.h> 51 #include <alpha/tc/tc_3000_500.h> 52 #ifndef NEW_SCC_DRIVER 53 #include <alpha/tc/sccvar.h> 54 #endif 55 56 #include <machine/z8530var.h> 57 #include <dev/tc/zs_ioasicvar.h> 58 59 #include <dev/scsipi/scsi_all.h> 60 #include <dev/scsipi/scsipi_all.h> 61 #include <dev/scsipi/scsiconf.h> 62 63 #include "wsdisplay.h" 64 65 void dec_3000_500_init __P((void)); 66 static void dec_3000_500_cons_init __P((void)); 67 static void dec_3000_500_device_register __P((struct device *, void *)); 68 69 static const char dec_3000_500_sp[] = "DEC 3000/400 (\"Sandpiper\")"; 70 static const char dec_3000_500_sf[] = "DEC 3000/500 (\"Flamingo\")"; 71 72 const struct alpha_variation_table dec_3000_500_variations[] = { 73 { SV_ST_SANDPIPER, dec_3000_500_sp }, 74 { SV_ST_FLAMINGO, dec_3000_500_sf }, 75 { SV_ST_HOTPINK, "DEC 3000/500X (\"Hot Pink\")" }, 76 { SV_ST_FLAMINGOPLUS, "DEC 3000/800 (\"Flamingo+\")" }, 77 { SV_ST_SANDPLUS, "DEC 3000/600 (\"Sandpiper+\")" }, 78 { SV_ST_SANDPIPER45, "DEC 3000/700 (\"Sandpiper45\")" }, 79 { SV_ST_FLAMINGO45, "DEC 3000/900 (\"Flamingo45\")" }, 80 { 0, NULL }, 81 }; 82 83 void 84 dec_3000_500_init() 85 { 86 u_int64_t variation; 87 88 platform.family = "DEC 3000/500 (\"Flamingo\")"; 89 90 if ((platform.model = alpha_dsr_sysname()) == NULL) { 91 variation = hwrpb->rpb_variation & SV_ST_MASK; 92 if (variation == SV_ST_ULTRA) { 93 /* These are really the same. */ 94 variation = SV_ST_FLAMINGOPLUS; 95 } 96 if ((platform.model = alpha_variation_name(variation, 97 dec_3000_500_variations)) == NULL) { 98 /* 99 * This is how things used to be done. 100 */ 101 if (variation == SV_ST_RESERVED) { 102 if (hwrpb->rpb_variation & SV_GRAPHICS) 103 platform.model = dec_3000_500_sf; 104 else 105 platform.model = dec_3000_500_sp; 106 } else 107 platform.model = alpha_unknown_sysname(); 108 } 109 } 110 111 platform.iobus = "tcasic"; 112 platform.cons_init = dec_3000_500_cons_init; 113 platform.device_register = dec_3000_500_device_register; 114 } 115 116 static void 117 dec_3000_500_cons_init() 118 { 119 struct ctb *ctb; 120 121 ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off); 122 123 #ifndef NEW_SCC_DRIVER 124 switch (ctb->ctb_term_type) { 125 case CTB_GRAPHICS: 126 alpha_donot_kludge_scc = 1; 127 return; 128 case CTB_PRINTERPORT: 129 return; 130 default: 131 goto badconsole; 132 } 133 #else 134 135 switch (ctb->ctb_term_type) { 136 case CTB_GRAPHICS: 137 #if NWSDISPLAY > 0 138 /* display console ... */ 139 if (zs_ioasic_lk201_cnattach(0x1e0000000, 0x00180000, 0) == 0 && 140 tc_3000_500_fb_cnattach( 141 CTB_TURBOSLOT_SLOT(ctb->ctb_turboslot)) == 0) { 142 break; 143 } 144 #endif 145 printf("consinit: Unable to init console on keyboard and "); 146 printf("TURBOchannel slot 0x%lx.\n", ctb->ctb_turboslot); 147 printf("Using serial console.\n"); 148 /* FALLTHROUGH */ 149 150 case CTB_PRINTERPORT: 151 /* serial console ... */ 152 /* 153 * XXX This could stand some cleanup... 154 */ 155 { 156 /* 157 * Delay to allow PROM putchars to complete. 158 * FIFO depth * character time, 159 * character time = (1000000 / (defaultrate / 10)) 160 */ 161 DELAY(160000000 / 9600); /* XXX */ 162 163 /* 164 * Console is channel B of the second SCC. 165 * XXX Should use ctb_line_off to get the 166 * XXX line parameters--these are the defaults. 167 */ 168 zs_ioasic_cnattach(0x1e0000000, 0x00180000, 1); 169 break; 170 } 171 172 default: 173 goto badconsole; 174 } 175 #endif 176 return; 177 badconsole: 178 printf("ctb->ctb_term_type = 0x%lx\n", ctb->ctb_term_type); 179 printf("ctb->ctb_turboslot = 0x%lx\n", ctb->ctb_turboslot); 180 181 panic("consinit: unknown console type %lu\n", 182 ctb->ctb_term_type); 183 } 184 185 static void 186 dec_3000_500_device_register(dev, aux) 187 struct device *dev; 188 void *aux; 189 { 190 static int found, initted, scsiboot, netboot; 191 static struct device *scsidev; 192 static struct device *tcdsdev; 193 struct bootdev_data *b = bootdev_data; 194 struct device *parent = dev->dv_parent; 195 struct cfdata *cf = dev->dv_cfdata; 196 struct cfdriver *cd = cf->cf_driver; 197 198 if (found) 199 return; 200 201 if (!initted) { 202 scsiboot = (strcmp(b->protocol, "SCSI") == 0); 203 netboot = (strcmp(b->protocol, "BOOTP") == 0) || 204 (strcmp(b->protocol, "MOP") == 0); 205 #if 0 206 printf("scsiboot = %d, netboot = %d\n", scsiboot, netboot); 207 #endif 208 initted = 1; 209 } 210 211 /* 212 * for scsi boot, we look for "tcds", make sure it has the 213 * right slot number, then find the "asc" on this tcds that 214 * as the right channel. then we find the actual scsi 215 * device we came from. note: no SCSI LUN support (yet). 216 */ 217 if (scsiboot && (strcmp(cd->cd_name, "tcds") == 0)) { 218 struct tc_attach_args *tcargs = aux; 219 220 if (b->slot != tcargs->ta_slot) 221 return; 222 223 tcdsdev = dev; 224 #if 0 225 printf("\ntcdsdev = %s\n", dev->dv_xname); 226 #endif 227 } 228 if (scsiboot && tcdsdev && 229 (strcmp(cd->cd_name, "asc") == 0)) { 230 struct tcdsdev_attach_args *ta = aux; 231 232 if (parent != (struct device *)tcdsdev) 233 return; 234 235 if (ta->tcdsda_chip != b->channel) 236 return; 237 238 scsidev = dev; 239 #if 0 240 printf("\nscsidev = %s\n", dev->dv_xname); 241 #endif 242 } 243 244 if (scsiboot && scsidev && 245 (strcmp(cd->cd_name, "sd") == 0 || 246 strcmp(cd->cd_name, "st") == 0 || 247 strcmp(cd->cd_name, "cd") == 0)) { 248 struct scsipibus_attach_args *sa = aux; 249 250 if (parent->dv_parent != scsidev) 251 return; 252 253 if (b->unit / 100 != sa->sa_periph->periph_target) 254 return; 255 256 /* XXX LUN! */ 257 258 switch (b->boot_dev_type) { 259 case 0: 260 if (strcmp(cd->cd_name, "sd") && 261 strcmp(cd->cd_name, "cd")) 262 return; 263 break; 264 case 1: 265 if (strcmp(cd->cd_name, "st")) 266 return; 267 break; 268 default: 269 return; 270 } 271 272 /* we've found it! */ 273 booted_device = dev; 274 #if 0 275 printf("\nbooted_device = %s\n", booted_device->dv_xname); 276 #endif 277 found = 1; 278 } 279 280 if (netboot) { 281 if (b->slot == 7 && strcmp(cd->cd_name, "le") == 0 && 282 strcmp(parent->dv_cfdata->cf_driver->cd_name, "ioasic") 283 == 0) { 284 /* 285 * no need to check ioasic_attach_args, since only 286 * one le on ioasic. 287 */ 288 289 booted_device = dev; 290 #if 0 291 printf("\nbooted_device = %s\n", booted_device->dv_xname); 292 #endif 293 found = 1; 294 return; 295 } 296 297 /* 298 * XXX GENERIC SUPPORT FOR TC NETWORK BOARDS 299 */ 300 } 301 } 302