]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/alpha/alpha/dec_kn20aa.c
This commit was generated by cvs2svn to compensate for changes in r52287,
[FreeBSD/FreeBSD.git] / sys / alpha / alpha / dec_kn20aa.c
1 /* $NetBSD: dec_kn20aa.c,v 1.38 1998/04/17 02:45:19 mjacob Exp $ */
2 /* $FreeBSD$ */
3
4 /*
5  * Copyright (c) 1995, 1996, 1997 Carnegie-Mellon University.
6  * All rights reserved.
7  *
8  * Author: Chris G. Demetriou
9  * 
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.
15  * 
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.
19  * 
20  * Carnegie Mellon requests users of this software to return to
21  *
22  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
23  *  School of Computer Science
24  *  Carnegie Mellon University
25  *  Pittsburgh PA 15213-3890
26  *
27  * any improvements or extensions that they make and grant Carnegie the
28  * rights to redistribute these changes.
29  */
30 /*
31  * Additional Copyright (c) 1997 by Matthew Jacob for NASA/Ames Research Center
32  */
33
34 #include "opt_ddb.h"
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/termios.h>
39
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>
48
49 #include "sio.h"
50 #include "sc.h"
51
52 #ifndef CONSPEED
53 #define CONSPEED TTYDEF_SPEED
54 #endif
55 static int comcnrate = CONSPEED;
56
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));
63
64 extern int siocnattach __P((int, int));
65 extern int siogdbattach __P((int, int));
66 extern int sccnattach __P((void));
67
68 #if 0
69 static void dec_kn20aa_device_register __P((struct device *, void *));
70 #endif
71
72 const struct alpha_variation_table dec_kn20aa_variations[] = {
73         { 0, "AlphaStation 500 or 600 (KN20AA)" },
74         { 0, NULL },
75 };
76 extern int comconsole; /* XXX for forcing comconsole when srm serial console is used */
77
78 void
79 dec_kn20aa_init()
80 {
81         u_int64_t variation;
82
83         platform.family = "AlphaStation 500 or 600 (KN20AA)";
84
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();
90         }
91
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;
98 }
99
100 static void
101 dec_kn20aa_cons_init()
102 {
103         struct ctb *ctb;
104
105         cia_init();
106
107 #ifdef DDB
108         siogdbattach(0x2f8, 9600);
109 #endif
110         ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off);
111
112         switch (ctb->ctb_term_type) {
113         case 2: 
114                 /* serial console ... */
115                 /* XXX */
116                 {
117                         /*
118                          * Delay to allow PROM putchars to complete.
119                          * FIFO depth * character time,
120                          * character time = (1000000 / (defaultrate / 10))
121                          */
122                         DELAY(160000000 / comcnrate);
123                         comconsole = 0;
124                         if (siocnattach(0x3f8, comcnrate))
125                                 panic("can't init serial console");
126
127                         break;
128                 }
129
130         case 3:
131                 /* display console ... */
132                 /* XXX */
133 #if NSC > 0
134                 sccnattach();
135 #else
136                 panic("not configured to use display && keyboard console");
137 #endif
138                 break;
139
140         default:
141                 printf("ctb->ctb_term_type = 0x%lx\n", ctb->ctb_term_type);
142                 printf("ctb->ctb_turboslot = 0x%lx\n", ctb->ctb_turboslot);
143
144                 panic("consinit: unknown console type %d\n",
145                     (int)ctb->ctb_term_type);
146         }
147 }
148 #if 0
149 static void
150 dec_kn20aa_device_register(dev, aux)
151         struct device *dev;
152         void *aux;
153 {
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;
160
161         if (found)
162                 return;
163
164         if (!initted) {
165                 scsiboot = (strcmp(b->protocol, "SCSI") == 0);
166                 netboot = (strcmp(b->protocol, "BOOTP") == 0);
167 #if 0
168                 printf("scsiboot = %d, netboot = %d\n", scsiboot, netboot);
169 #endif
170                 initted =1;
171         }
172
173         if (pcidev == NULL) {
174                 if (strcmp(cd->cd_name, "pci"))
175                         return;
176                 else {
177                         struct pcibus_attach_args *pba = aux;
178
179                         if ((b->slot / 1000) != pba->pba_bus)
180                                 return;
181         
182                         pcidev = dev;
183 #if 0
184                         printf("\npcidev = %s\n", pcidev->dv_xname);
185 #endif
186                         return;
187                 }
188         }
189
190         if (scsiboot && (scsidev == NULL)) {
191                 if (parent != pcidev)
192                         return;
193                 else {
194                         struct pci_attach_args *pa = aux;
195
196                         if ((b->slot % 1000) != pa->pa_device)
197                                 return;
198
199                         /* XXX function? */
200         
201                         scsidev = dev;
202 #if 0
203                         printf("\nscsidev = %s\n", scsidev->dv_xname);
204 #endif
205                         return;
206                 }
207         }
208
209         if (scsiboot &&
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;
214
215                 if (parent->dv_parent != scsidev)
216                         return;
217
218                 if (b->unit / 100 != sa->sa_sc_link->scsipi_scsi.target)
219                         return;
220
221                 /* XXX LUN! */
222
223                 switch (b->boot_dev_type) {
224                 case 0:
225                         if (strcmp(cd->cd_name, "sd") &&
226                             strcmp(cd->cd_name, "cd"))
227                                 return;
228                         break;
229                 case 1:
230                         if (strcmp(cd->cd_name, "st"))
231                                 return;
232                         break;
233                 default:
234                         return;
235                 }
236
237                 /* we've found it! */
238                 booted_device = dev;
239 #if 0
240                 printf("\nbooted_device = %s\n", booted_device->dv_xname);
241 #endif
242                 found = 1;
243         }
244
245         if (netboot) {
246                 if (parent != pcidev)
247                         return;
248                 else {
249                         struct pci_attach_args *pa = aux;
250
251                         if ((b->slot % 1000) != pa->pa_device)
252                                 return;
253
254                         /* XXX function? */
255         
256                         booted_device = dev;
257 #if 0
258                         printf("\nbooted_device = %s\n", booted_device->dv_xname);
259 #endif
260                         found = 1;
261                         return;
262                 }
263         }
264 }
265 #endif
266
267 #define KN20AA_MAX_IRQ  32
268 void
269 dec_kn20aa_intr_init()
270 {
271     /*
272      * Enable ISA-PCI cascade interrupt.
273      */
274     dec_kn20aa_intr_enable(31);
275 }
276
277 void
278 dec_kn20aa_intr_map(void *arg)
279 {
280         pcicfgregs *cfg = (pcicfgregs *)arg;
281         /*
282          * Slot->interrupt translation.  Appears to work, though it
283          * may not hold up forever.
284          *
285          * The DEC engineers who did this hardware obviously engaged
286          * in random drug testing.
287          */
288         switch (cfg->slot) {
289         case 11:
290         case 12:
291                 cfg->intline = ((cfg->slot - 11) + 0) * 4;
292                 break;
293
294         case 7:
295                 cfg->intline = 8;
296                 break;
297
298         case 9:
299                 cfg->intline = 12;
300                 break;
301
302         case 6:                                 /* 21040 on AlphaStation 500 */
303                 cfg->intline = 13;
304                 break;
305
306         case 8:
307                 cfg->intline = 16;
308                 break;
309
310         case 10:                                /* 8275EB on AlphaStation 500 */
311                 return;
312
313         default:
314                 if(!cfg->bus){
315                         printf("dec_kn20aa_intr_map: weird slot %d\n",
316                                cfg->slot);
317                         return;
318                 } else {
319                         cfg->intline = cfg->slot;
320                 }
321         }
322         
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",
326                     cfg->intline);
327
328 }
329
330 void
331 dec_kn20aa_intr_enable(irq)
332         int irq;
333 {
334
335         /*
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.
340          */
341         alpha_mb();
342         REGVAL(0x8780000000L + 0x40L) |= (1 << irq);    /* XXX */
343         alpha_mb();
344 }
345
346 void
347 dec_kn20aa_intr_disable(irq)
348         int irq;
349 {
350
351         alpha_mb();
352         REGVAL(0x8780000000L + 0x40L) &= ~(1 << irq);   /* XXX */
353         alpha_mb();
354 }