1 /* $NetBSD: dec_kn20aa.c,v 1.38 1998/04/17 02:45:19 mjacob Exp $ */
5 * Copyright (c) 1995, 1996, 1997 Carnegie-Mellon University.
8 * Author: Chris G. Demetriou
10 * Permission to use, copy, modify and distribute this software and
11 * its documentation is hereby granted, provided that both the copyright
12 * notice and this permission notice appear in all copies of the
13 * software, derivative works or modified versions, and any portions
14 * thereof, and that both notices appear in supporting documentation.
16 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
20 * Carnegie Mellon requests users of this software to return to
22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23 * School of Computer Science
24 * Carnegie Mellon University
25 * Pittsburgh PA 15213-3890
27 * any improvements or extensions that they make and grant Carnegie the
28 * rights to redistribute these changes.
31 * Additional Copyright (c) 1997 by Matthew Jacob for NASA/Ames Research Center
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/termios.h>
40 #include <machine/rpb.h>
41 #include <machine/cpuconf.h>
42 #include <machine/clock.h>
43 #include <pci/pcireg.h>
44 #include <pci/pcivar.h>
45 #include <pci/pci_ioctl.h>
46 #include <alpha/pci/ciareg.h>
47 #include <alpha/pci/ciavar.h>
53 #define CONSPEED TTYDEF_SPEED
55 static int comcnrate = CONSPEED;
57 void dec_kn20aa_init __P((void));
58 static void dec_kn20aa_cons_init __P((void));
59 static void dec_kn20aa_intr_init __P((void));
60 static void dec_kn20aa_intr_map __P((void *));
61 static void dec_kn20aa_intr_disable __P((int));
62 static void dec_kn20aa_intr_enable __P((int));
64 extern int siocnattach __P((int, int));
65 extern int siogdbattach __P((int, int));
66 extern int sccnattach __P((void));
69 static void dec_kn20aa_device_register __P((struct device *, void *));
72 const struct alpha_variation_table dec_kn20aa_variations[] = {
73 { 0, "AlphaStation 500 or 600 (KN20AA)" },
76 extern int comconsole; /* XXX for forcing comconsole when srm serial console is used */
83 platform.family = "AlphaStation 500 or 600 (KN20AA)";
85 if ((platform.model = alpha_dsr_sysname()) == NULL) {
86 variation = hwrpb->rpb_variation & SV_ST_MASK;
87 if ((platform.model = alpha_variation_name(variation,
88 dec_kn20aa_variations)) == NULL)
89 platform.model = alpha_unknown_sysname();
92 platform.iobus = "cia";
93 platform.cons_init = dec_kn20aa_cons_init;
94 platform.pci_intr_init = dec_kn20aa_intr_init;
95 platform.pci_intr_map = dec_kn20aa_intr_map;
96 platform.pci_intr_disable = dec_kn20aa_intr_disable;
97 platform.pci_intr_enable = dec_kn20aa_intr_enable;
101 dec_kn20aa_cons_init()
108 siogdbattach(0x2f8, 9600);
110 ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off);
112 switch (ctb->ctb_term_type) {
114 /* serial console ... */
118 * Delay to allow PROM putchars to complete.
119 * FIFO depth * character time,
120 * character time = (1000000 / (defaultrate / 10))
122 DELAY(160000000 / comcnrate);
124 if (siocnattach(0x3f8, comcnrate))
125 panic("can't init serial console");
131 /* display console ... */
136 panic("not configured to use display && keyboard console");
141 printf("ctb->ctb_term_type = 0x%lx\n", ctb->ctb_term_type);
142 printf("ctb->ctb_turboslot = 0x%lx\n", ctb->ctb_turboslot);
144 panic("consinit: unknown console type %d\n",
145 (int)ctb->ctb_term_type);
150 dec_kn20aa_device_register(dev, aux)
154 static int found, initted, scsiboot, netboot;
155 static struct device *pcidev, *scsidev;
156 struct bootdev_data *b = bootdev_data;
157 struct device *parent = dev->dv_parent;
158 struct cfdata *cf = dev->dv_cfdata;
159 struct cfdriver *cd = cf->cf_driver;
165 scsiboot = (strcmp(b->protocol, "SCSI") == 0);
166 netboot = (strcmp(b->protocol, "BOOTP") == 0);
168 printf("scsiboot = %d, netboot = %d\n", scsiboot, netboot);
173 if (pcidev == NULL) {
174 if (strcmp(cd->cd_name, "pci"))
177 struct pcibus_attach_args *pba = aux;
179 if ((b->slot / 1000) != pba->pba_bus)
184 printf("\npcidev = %s\n", pcidev->dv_xname);
190 if (scsiboot && (scsidev == NULL)) {
191 if (parent != pcidev)
194 struct pci_attach_args *pa = aux;
196 if ((b->slot % 1000) != pa->pa_device)
203 printf("\nscsidev = %s\n", scsidev->dv_xname);
210 (!strcmp(cd->cd_name, "sd") ||
211 !strcmp(cd->cd_name, "st") ||
212 !strcmp(cd->cd_name, "cd"))) {
213 struct scsipibus_attach_args *sa = aux;
215 if (parent->dv_parent != scsidev)
218 if (b->unit / 100 != sa->sa_sc_link->scsipi_scsi.target)
223 switch (b->boot_dev_type) {
225 if (strcmp(cd->cd_name, "sd") &&
226 strcmp(cd->cd_name, "cd"))
230 if (strcmp(cd->cd_name, "st"))
237 /* we've found it! */
240 printf("\nbooted_device = %s\n", booted_device->dv_xname);
246 if (parent != pcidev)
249 struct pci_attach_args *pa = aux;
251 if ((b->slot % 1000) != pa->pa_device)
258 printf("\nbooted_device = %s\n", booted_device->dv_xname);
267 #define KN20AA_MAX_IRQ 32
269 dec_kn20aa_intr_init()
272 * Enable ISA-PCI cascade interrupt.
274 dec_kn20aa_intr_enable(31);
278 dec_kn20aa_intr_map(void *arg)
280 pcicfgregs *cfg = (pcicfgregs *)arg;
282 * Slot->interrupt translation. Appears to work, though it
283 * may not hold up forever.
285 * The DEC engineers who did this hardware obviously engaged
286 * in random drug testing.
291 cfg->intline = ((cfg->slot - 11) + 0) * 4;
302 case 6: /* 21040 on AlphaStation 500 */
310 case 10: /* 8275EB on AlphaStation 500 */
315 printf("dec_kn20aa_intr_map: weird slot %d\n",
319 cfg->intline = cfg->slot;
323 cfg->intline += cfg->bus*16;
324 if (cfg->intline > KN20AA_MAX_IRQ)
325 panic("dec_kn20aa_intr_map: cfg->intline too large (%d)\n",
331 dec_kn20aa_intr_enable(irq)
336 * From disassembling small bits of the OSF/1 kernel:
337 * the following appears to enable a given interrupt request.
338 * "blech." I'd give valuable body parts for better docs or
339 * for a good decompiler.
342 REGVAL(0x8780000000L + 0x40L) |= (1 << irq); /* XXX */
347 dec_kn20aa_intr_disable(irq)
352 REGVAL(0x8780000000L + 0x40L) &= ~(1 << irq); /* XXX */