1/* $NetBSD: dec_axppci_33.c,v 1.65 2011/06/14 15:34:22 matt 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.65 2011/06/14 15:34:22 matt 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 75static int comcnrate = CONSPEED; 76 77void dec_axppci_33_init(void); 78static void dec_axppci_33_cons_init(void); 79static void dec_axppci_33_device_register(device_t, void *); 80 81#ifdef KGDB 82#include <machine/db_machdep.h> 83 84static const char *kgdb_devlist[] = { 85 "com", 86 NULL, 87}; 88#endif /* KGDB */ 89 90const struct alpha_variation_table dec_axppci_33_variations[] = { 91 { 0, "Alpha PC AXPpci33 (\"NoName\")" }, 92 { 0, NULL }, 93}; 94 95static struct lca_config *lca_preinit(void); 96 97static struct lca_config * 98lca_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 116void 117dec_axppci_33_init(void) 118{ 119 int cfg0val; 120 uint64_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 168static void 169dec_axppci_33_cons_init(void) 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 230static void 231dec_axppci_33_device_register(device_t dev, void *aux) 232{ 233 static int found, initted, diskboot, netboot; 234 static device_t pcidev, ctrlrdev; 235 struct bootdev_data *b = bootdev_data; 236 device_t 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", device_xname(dev)); 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", device_xname(dev)); 284#endif 285 found = 1; 286 } else { 287 ctrlrdev = dev; 288#if 0 289 printf("\nctrlrdev = %s\n", device_xname(dev)); 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", device_xname(dev)); 319#endif 320 found = 1; 321 } 322} 323