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 <alpha/pci/ciareg.h>
46 #include <alpha/pci/ciavar.h>
52 #define CONSPEED TTYDEF_SPEED
54 static int comcnrate = CONSPEED;
56 void dec_kn20aa_init __P((void));
57 static void dec_kn20aa_cons_init __P((void));
58 static void dec_kn20aa_intr_init __P((void));
59 static void dec_kn20aa_intr_map __P((void *));
60 static void dec_kn20aa_intr_disable __P((int));
61 static void dec_kn20aa_intr_enable __P((int));
63 extern int siocnattach __P((int, int));
64 extern int siogdbattach __P((int, int));
65 extern int sccnattach __P((void));
68 static void dec_kn20aa_device_register __P((struct device *, void *));
71 const struct alpha_variation_table dec_kn20aa_variations[] = {
72 { 0, "AlphaStation 500 or 600 (KN20AA)" },
75 extern int comconsole; /* XXX for forcing comconsole when srm serial console is used */
82 platform.family = "AlphaStation 500 or 600 (KN20AA)";
84 if ((platform.model = alpha_dsr_sysname()) == NULL) {
85 variation = hwrpb->rpb_variation & SV_ST_MASK;
86 if ((platform.model = alpha_variation_name(variation,
87 dec_kn20aa_variations)) == NULL)
88 platform.model = alpha_unknown_sysname();
91 platform.iobus = "cia";
92 platform.cons_init = dec_kn20aa_cons_init;
93 platform.pci_intr_init = dec_kn20aa_intr_init;
94 platform.pci_intr_map = dec_kn20aa_intr_map;
95 platform.pci_intr_disable = dec_kn20aa_intr_disable;
96 platform.pci_intr_enable = dec_kn20aa_intr_enable;
100 dec_kn20aa_cons_init()
107 siogdbattach(0x2f8, 9600);
109 ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off);
111 switch (ctb->ctb_term_type) {
113 /* serial console ... */
117 * Delay to allow PROM putchars to complete.
118 * FIFO depth * character time,
119 * character time = (1000000 / (defaultrate / 10))
121 DELAY(160000000 / comcnrate);
123 if (siocnattach(0x3f8, comcnrate))
124 panic("can't init serial console");
130 /* display console ... */
135 panic("not configured to use display && keyboard console");
140 printf("ctb->ctb_term_type = 0x%lx\n", ctb->ctb_term_type);
141 printf("ctb->ctb_turboslot = 0x%lx\n", ctb->ctb_turboslot);
143 panic("consinit: unknown console type %d\n",
144 (int)ctb->ctb_term_type);
149 dec_kn20aa_device_register(dev, aux)
153 static int found, initted, scsiboot, netboot;
154 static struct device *pcidev, *scsidev;
155 struct bootdev_data *b = bootdev_data;
156 struct device *parent = dev->dv_parent;
157 struct cfdata *cf = dev->dv_cfdata;
158 struct cfdriver *cd = cf->cf_driver;
164 scsiboot = (strcmp(b->protocol, "SCSI") == 0);
165 netboot = (strcmp(b->protocol, "BOOTP") == 0);
167 printf("scsiboot = %d, netboot = %d\n", scsiboot, netboot);
172 if (pcidev == NULL) {
173 if (strcmp(cd->cd_name, "pci"))
176 struct pcibus_attach_args *pba = aux;
178 if ((b->slot / 1000) != pba->pba_bus)
183 printf("\npcidev = %s\n", pcidev->dv_xname);
189 if (scsiboot && (scsidev == NULL)) {
190 if (parent != pcidev)
193 struct pci_attach_args *pa = aux;
195 if ((b->slot % 1000) != pa->pa_device)
202 printf("\nscsidev = %s\n", scsidev->dv_xname);
209 (!strcmp(cd->cd_name, "sd") ||
210 !strcmp(cd->cd_name, "st") ||
211 !strcmp(cd->cd_name, "cd"))) {
212 struct scsipibus_attach_args *sa = aux;
214 if (parent->dv_parent != scsidev)
217 if (b->unit / 100 != sa->sa_sc_link->scsipi_scsi.target)
222 switch (b->boot_dev_type) {
224 if (strcmp(cd->cd_name, "sd") &&
225 strcmp(cd->cd_name, "cd"))
229 if (strcmp(cd->cd_name, "st"))
236 /* we've found it! */
239 printf("\nbooted_device = %s\n", booted_device->dv_xname);
245 if (parent != pcidev)
248 struct pci_attach_args *pa = aux;
250 if ((b->slot % 1000) != pa->pa_device)
257 printf("\nbooted_device = %s\n", booted_device->dv_xname);
266 #define KN20AA_MAX_IRQ 32
268 dec_kn20aa_intr_init()
271 * Enable ISA-PCI cascade interrupt.
273 dec_kn20aa_intr_enable(31);
277 dec_kn20aa_intr_map(void *arg)
279 pcicfgregs *cfg = (pcicfgregs *)arg;
281 * Slot->interrupt translation. Appears to work, though it
282 * may not hold up forever.
284 * The DEC engineers who did this hardware obviously engaged
285 * in random drug testing.
290 cfg->intline = ((cfg->slot - 11) + 0) * 4;
301 case 6: /* 21040 on AlphaStation 500 */
309 case 10: /* 8275EB on AlphaStation 500 */
314 printf("dec_kn20aa_intr_map: weird slot %d\n",
318 cfg->intline = cfg->slot;
322 cfg->intline += cfg->bus*16;
323 if (cfg->intline > KN20AA_MAX_IRQ)
324 panic("dec_kn20aa_intr_map: cfg->intline too large (%d)\n",
330 dec_kn20aa_intr_enable(irq)
335 * From disassembling small bits of the OSF/1 kernel:
336 * the following appears to enable a given interrupt request.
337 * "blech." I'd give valuable body parts for better docs or
338 * for a good decompiler.
341 REGVAL(0x8780000000L + 0x40L) |= (1 << irq); /* XXX */
346 dec_kn20aa_intr_disable(irq)
351 REGVAL(0x8780000000L + 0x40L) &= ~(1 << irq); /* XXX */