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