1 /* $NetBSD: dec_axppci_33.c,v 1.64 2009/03/18 10:22:22 cegger 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_axppci_33.c,v 1.64 2009/03/18 10:22:22 cegger 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/alpha.h> 50 #include <machine/autoconf.h> 51 #include <machine/cpuconf.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/lcareg.h> 64 #include <alpha/pci/lcavar.h> 65 66 #include <dev/scsipi/scsi_all.h> 67 #include <dev/scsipi/scsipi_all.h> 68 #include <dev/scsipi/scsiconf.h> 69 70 #include "pckbd.h" 71 72 #ifndef CONSPEED 73 #define CONSPEED TTYDEF_SPEED 74 #endif 75 static int comcnrate = CONSPEED; 76 77 void dec_axppci_33_init(void); 78 static void dec_axppci_33_cons_init(void); 79 static void dec_axppci_33_device_register(struct device *, void *); 80 81 #ifdef KGDB 82 #include <machine/db_machdep.h> 83 84 static const char *kgdb_devlist[] = { 85 "com", 86 NULL, 87 }; 88 #endif /* KGDB */ 89 90 const struct alpha_variation_table dec_axppci_33_variations[] = { 91 { 0, "Alpha PC AXPpci33 (\"NoName\")" }, 92 { 0, NULL }, 93 }; 94 95 static struct lca_config *lca_preinit(void); 96 97 static struct lca_config * 98 lca_preinit(void) 99 { 100 extern struct lca_config lca_configuration; 101 102 lca_init(&lca_configuration, 0); 103 return &lca_configuration; 104 } 105 106 #define NSIO_PORT 0x26e /* Hardware enabled option: 0x398 */ 107 #define NSIO_BASE 0 108 #define NSIO_INDEX NSIO_BASE 109 #define NSIO_DATA 1 110 #define NSIO_SIZE 2 111 #define NSIO_CFG0 0 112 #define NSIO_CFG1 1 113 #define NSIO_CFG2 2 114 #define NSIO_IDE_ENABLE 0x40 115 116 void 117 dec_axppci_33_init() 118 { 119 int cfg0val; 120 u_int64_t variation; 121 bus_space_tag_t iot; 122 struct lca_config *lcp; 123 bus_space_handle_t nsio; 124 #define A33_NSIOBARRIER(type) bus_space_barrier(iot, nsio,\ 125 NSIO_BASE, NSIO_SIZE, (type)) 126 127 platform.family = "DEC AXPpci"; 128 129 if ((platform.model = alpha_dsr_sysname()) == NULL) { 130 variation = hwrpb->rpb_variation & SV_ST_MASK; 131 if ((platform.model = alpha_variation_name(variation, 132 dec_axppci_33_variations)) == NULL) 133 platform.model = alpha_unknown_sysname(); 134 } 135 136 platform.iobus = "lca"; 137 platform.cons_init = dec_axppci_33_cons_init; 138 platform.device_register = dec_axppci_33_device_register; 139 140 lcp = lca_preinit(); 141 iot = &lcp->lc_iot; 142 if (bus_space_map(iot, NSIO_PORT, NSIO_SIZE, 0, &nsio)) 143 return; 144 145 bus_space_write_1(iot, nsio, NSIO_INDEX, NSIO_CFG0); 146 A33_NSIOBARRIER(BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 147 cfg0val = bus_space_read_1(iot, nsio, NSIO_DATA); 148 149 cfg0val |= NSIO_IDE_ENABLE; 150 151 bus_space_write_1(iot, nsio, NSIO_INDEX, NSIO_CFG0); 152 A33_NSIOBARRIER(BUS_SPACE_BARRIER_WRITE); 153 bus_space_write_1(iot, nsio, NSIO_DATA, cfg0val); 154 A33_NSIOBARRIER(BUS_SPACE_BARRIER_WRITE); 155 bus_space_write_1(iot, nsio, NSIO_DATA, cfg0val); 156 157 /* Leave nsio mapped to catch any accidental port space collisions */ 158 159 /* 160 * AXPpci33 systems have either 0, 256K, or 1M secondary 161 * caches. Default to middle-of-the-road. 162 * 163 * XXX Dynamically size it! 164 */ 165 uvmexp.ncolors = atop(256 * 1024); 166 } 167 168 static void 169 dec_axppci_33_cons_init() 170 { 171 struct ctb *ctb; 172 struct lca_config *lcp; 173 174 lcp = lca_preinit(); 175 176 ctb = (struct ctb *)(((char *)hwrpb) + hwrpb->rpb_ctb_off); 177 178 switch (ctb->ctb_term_type) { 179 case CTB_PRINTERPORT: 180 /* serial console ... */ 181 /* XXX */ 182 { 183 /* 184 * Delay to allow PROM putchars to complete. 185 * FIFO depth * character time, 186 * character time = (1000000 / (defaultrate / 10)) 187 */ 188 DELAY(160000000 / comcnrate); 189 190 if(comcnattach(&lcp->lc_iot, 0x3f8, comcnrate, 191 COM_FREQ, COM_TYPE_NORMAL, 192 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8)) 193 panic("can't init serial console"); 194 195 break; 196 } 197 198 case CTB_GRAPHICS: 199 #if NPCKBD > 0 200 /* display console ... */ 201 /* XXX */ 202 (void) pckbc_cnattach(&lcp->lc_iot, IO_KBD, KBCMDP, 203 PCKBC_KBD_SLOT); 204 205 if (CTB_TURBOSLOT_TYPE(ctb->ctb_turboslot) == 206 CTB_TURBOSLOT_TYPE_ISA) 207 isa_display_console(&lcp->lc_iot, &lcp->lc_memt); 208 else 209 pci_display_console(&lcp->lc_iot, &lcp->lc_memt, 210 &lcp->lc_pc, CTB_TURBOSLOT_BUS(ctb->ctb_turboslot), 211 CTB_TURBOSLOT_SLOT(ctb->ctb_turboslot), 0); 212 #else 213 panic("not configured to use display && keyboard console"); 214 #endif 215 break; 216 217 default: 218 printf("ctb->ctb_term_type = 0x%lx\n", ctb->ctb_term_type); 219 printf("ctb->ctb_turboslot = 0x%lx\n", ctb->ctb_turboslot); 220 221 panic("consinit: unknown console type %ld", 222 ctb->ctb_term_type); 223 } 224 #ifdef KGDB 225 /* Attach the KGDB device. */ 226 alpha_kgdb_init(kgdb_devlist, &lcp->lc_iot); 227 #endif /* KGDB */ 228 } 229 230 static void 231 dec_axppci_33_device_register(struct device *dev, void *aux) 232 { 233 static int found, initted, diskboot, netboot; 234 static struct device *pcidev, *ctrlrdev; 235 struct bootdev_data *b = bootdev_data; 236 struct device *parent = device_parent(dev); 237 238 if (found) 239 return; 240 241 if (!initted) { 242 diskboot = (strcasecmp(b->protocol, "SCSI") == 0); 243 netboot = (strcasecmp(b->protocol, "BOOTP") == 0) || 244 (strcasecmp(b->protocol, "MOP") == 0); 245 #if 0 246 printf("diskboot = %d, netboot = %d\n", diskboot, netboot); 247 #endif 248 initted =1; 249 } 250 251 if (pcidev == NULL) { 252 if (!device_is_a(dev, "pci")) 253 return; 254 else { 255 struct pcibus_attach_args *pba = aux; 256 257 if ((b->slot / 1000) != pba->pba_bus) 258 return; 259 260 pcidev = dev; 261 #if 0 262 printf("\npcidev = %s\n", dev->dv_xname); 263 #endif 264 return; 265 } 266 } 267 268 if (ctrlrdev == NULL) { 269 if (parent != pcidev) 270 return; 271 else { 272 struct pci_attach_args *pa = aux; 273 int slot; 274 275 slot = pa->pa_bus * 1000 + pa->pa_function * 100 + 276 pa->pa_device; 277 if (b->slot != slot) 278 return; 279 280 if (netboot) { 281 booted_device = dev; 282 #if 0 283 printf("\nbooted_device = %s\n", dev->dv_xname); 284 #endif 285 found = 1; 286 } else { 287 ctrlrdev = dev; 288 #if 0 289 printf("\nctrlrdev = %s\n", dev->dv_xname); 290 #endif 291 } 292 return; 293 } 294 } 295 296 if (!diskboot) 297 return; 298 299 if (device_is_a(dev, "sd") || 300 device_is_a(dev, "st") || 301 device_is_a(dev, "cd")) { 302 struct scsipibus_attach_args *sa = aux; 303 struct scsipi_periph *periph = sa->sa_periph; 304 int unit; 305 306 if (device_parent(parent) != ctrlrdev) 307 return; 308 309 unit = periph->periph_target * 100 + periph->periph_lun; 310 if (b->unit != unit) 311 return; 312 if (b->channel != periph->periph_channel->chan_channel) 313 return; 314 315 /* we've found it! */ 316 booted_device = dev; 317 #if 0 318 printf("\nbooted_device = %s\n", dev->dv_xname); 319 #endif 320 found = 1; 321 } 322 } 323