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