1/* $NetBSD: dec_kn20aa.c,v 1.63 2011/07/01 19:22:35 dyoung 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_kn20aa.c,v 1.63 2011/07/01 19:22:35 dyoung 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/rpb.h> 47#include <machine/autoconf.h> 48#include <machine/cpuconf.h> 49#include <sys/bus.h> 50#include <machine/alpha.h> 51#include <machine/logout.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/ciareg.h> 64#include <alpha/pci/ciavar.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_kn20aa_init(void); 78static void dec_kn20aa_cons_init(void); 79static void dec_kn20aa_device_register(device_t, void *); 80 81static void dec_kn20aa_mcheck_handler 82(unsigned long, struct trapframe *, unsigned long, unsigned long); 83 84static void dec_kn20aa_mcheck(unsigned long, unsigned long, 85 unsigned long, struct trapframe *); 86 87#ifdef KGDB 88#include <machine/db_machdep.h> 89 90static const char *kgdb_devlist[] = { 91 "com", 92 NULL, 93}; 94#endif /* KGDB */ 95 96const struct alpha_variation_table dec_kn20aa_variations[] = { 97 { 0, "AlphaStation 500 or 600 (KN20AA)" }, 98 { 0, NULL }, 99}; 100 101void 102dec_kn20aa_init(void) 103{ 104 uint64_t variation; 105 106 platform.family = "AlphaStation 500 or 600 (KN20AA)"; 107 108 if ((platform.model = alpha_dsr_sysname()) == NULL) { 109 variation = hwrpb->rpb_variation & SV_ST_MASK; 110 if ((platform.model = alpha_variation_name(variation, 111 dec_kn20aa_variations)) == NULL) 112 platform.model = alpha_unknown_sysname(); 113 } 114 115 platform.iobus = "cia"; 116 platform.cons_init = dec_kn20aa_cons_init; 117 platform.device_register = dec_kn20aa_device_register; 118 platform.mcheck_handler = dec_kn20aa_mcheck_handler; 119} 120 121static void 122dec_kn20aa_cons_init(void) 123{ 124 struct ctb *ctb; 125 struct cia_config *ccp; 126 extern struct cia_config cia_configuration; 127 128 ccp = &cia_configuration; 129 cia_init(ccp, 0); 130 131 ctb = (struct ctb *)(((char *)hwrpb) + hwrpb->rpb_ctb_off); 132 133 switch (ctb->ctb_term_type) { 134 case CTB_PRINTERPORT: 135 /* serial console ... */ 136 /* XXX */ 137 { 138 /* 139 * Delay to allow PROM putchars to complete. 140 * FIFO depth * character time, 141 * character time = (1000000 / (defaultrate / 10)) 142 */ 143 DELAY(160000000 / comcnrate); 144 145 if(comcnattach(&ccp->cc_iot, 0x3f8, comcnrate, 146 COM_FREQ, COM_TYPE_NORMAL, 147 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8)) 148 panic("can't init serial console"); 149 150 break; 151 } 152 153 case CTB_GRAPHICS: 154#if NPCKBD > 0 155 /* display console ... */ 156 /* XXX */ 157 (void) pckbc_cnattach(&ccp->cc_iot, IO_KBD, KBCMDP, 158 PCKBC_KBD_SLOT); 159 160 if (CTB_TURBOSLOT_TYPE(ctb->ctb_turboslot) == 161 CTB_TURBOSLOT_TYPE_ISA) 162 isa_display_console(&ccp->cc_iot, &ccp->cc_memt); 163 else 164 pci_display_console(&ccp->cc_iot, &ccp->cc_memt, 165 &ccp->cc_pc, CTB_TURBOSLOT_BUS(ctb->ctb_turboslot), 166 CTB_TURBOSLOT_SLOT(ctb->ctb_turboslot), 0); 167#else 168 panic("not configured to use display && keyboard console"); 169#endif 170 break; 171 172 default: 173 printf("ctb->ctb_term_type = 0x%lx\n", ctb->ctb_term_type); 174 printf("ctb->ctb_turboslot = 0x%lx\n", ctb->ctb_turboslot); 175 176 panic("consinit: unknown console type %ld", 177 ctb->ctb_term_type); 178 } 179#ifdef KGDB 180 /* Attach the KGDB device. */ 181 alpha_kgdb_init(kgdb_devlist, &ccp->cc_iot); 182#endif /* KGDB */ 183} 184 185static void 186dec_kn20aa_device_register(device_t dev, void *aux) 187{ 188 static int found, initted, diskboot, netboot; 189 static device_t pcidev, ctrlrdev; 190 struct bootdev_data *b = bootdev_data; 191 device_t parent = device_parent(dev); 192 193 if (found) 194 return; 195 196 if (!initted) { 197 diskboot = (strcasecmp(b->protocol, "SCSI") == 0); 198 netboot = (strcasecmp(b->protocol, "BOOTP") == 0) || 199 (strcasecmp(b->protocol, "MOP") == 0); 200#if 0 201 printf("diskboot = %d, netboot = %d\n", diskboot, netboot); 202#endif 203 initted =1; 204 } 205 206 if (pcidev == NULL) { 207 if (!device_is_a(dev, "pci")) 208 return; 209 else { 210 struct pcibus_attach_args *pba = aux; 211 212 if ((b->slot / 1000) != pba->pba_bus) 213 return; 214 215 pcidev = dev; 216#if 0 217 printf("\npcidev = %s\n", device_xname(dev)); 218#endif 219 return; 220 } 221 } 222 223 if (ctrlrdev == NULL) { 224 if (parent != pcidev) 225 return; 226 else { 227 struct pci_attach_args *pa = aux; 228 int slot; 229 230 slot = pa->pa_bus * 1000 + pa->pa_function * 100 + 231 pa->pa_device; 232 if (b->slot != slot) 233 return; 234 235 if (netboot) { 236 booted_device = dev; 237#if 0 238 printf("\nbooted_device = %s\n", device_xname(dev)); 239#endif 240 found = 1; 241 } else { 242 ctrlrdev = dev; 243#if 0 244 printf("\nctrlrdev = %s\n", device_xname(dev)); 245#endif 246 } 247 return; 248 } 249 } 250 251 if (!diskboot) 252 return; 253 254 if (device_is_a(dev, "sd") || 255 device_is_a(dev, "st") || 256 device_is_a(dev, "cd")) { 257 struct scsipibus_attach_args *sa = aux; 258 struct scsipi_periph *periph = sa->sa_periph; 259 int unit; 260 261 if (device_parent(parent) != ctrlrdev) 262 return; 263 264 unit = periph->periph_target * 100 + periph->periph_lun; 265 if (b->unit != unit) 266 return; 267 if (b->channel != periph->periph_channel->chan_channel) 268 return; 269 270 /* we've found it! */ 271 booted_device = dev; 272#if 0 273 printf("\nbooted_device = %s\n", device_xname(dev)); 274#endif 275 found = 1; 276 } 277} 278 279static void 280dec_kn20aa_mcheck(unsigned long mces, unsigned long type, unsigned long logout, struct trapframe *framep) 281{ 282 struct mchkinfo *mcp; 283 mc_hdr_ev5 *hdr; 284 mc_uc_ev5 *mptr; 285 286 /* 287 * If we expected a machine check, just go handle it in common code. 288 */ 289 mcp = &curcpu()->ci_mcinfo; 290 if (mcp->mc_expected) { 291 machine_check(mces, framep, type, logout); 292 return; 293 } 294 295 hdr = (mc_hdr_ev5 *) logout; 296 mptr = (mc_uc_ev5 *) (logout + sizeof (*hdr)); 297 298 /* 299 * Now we can finally print some stuff... 300 */ 301 ev5_logout_print(hdr, mptr); 302 303 machine_check(mces, framep, type, logout); 304} 305 306static void 307dec_kn20aa_mcheck_handler(unsigned long mces, struct trapframe *framep, unsigned long vector, unsigned long param) 308{ 309 310 switch (vector) { 311 case ALPHA_SYS_MCHECK: 312 case ALPHA_PROC_MCHECK: 313 dec_kn20aa_mcheck(mces, vector, param, framep); 314 break; 315 default: 316 printf("KN20AA_MCHECK: unknown check vector 0x%lx\n", vector); 317 machine_check(mces, framep, vector, param); 318 break; 319 } 320} 321