]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/alpha/alpha/dec_1000a.c
This commit was generated by cvs2svn to compensate for changes in r57419,
[FreeBSD/FreeBSD.git] / sys / alpha / alpha / dec_1000a.c
1 /* $NetBSD: dec_1000a.c,v 1.5 1999/04/15 22:06:47 thorpej Exp $ */
2
3 /*
4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is based on dec_kn20aa.c, written by Chris G. Demetriou at
8  * Carnegie-Mellon University. Platform support for Noritake, Pintake, and
9  * Corelle by Ross Harvey with copyright assignment by permission of Avalon
10  * Computer Systems, Inc.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *      This product includes software developed by the NetBSD
23  *      Foundation, Inc. and its contributors.
24  * 4. Neither the name of The NetBSD Foundation nor the names of its
25  *    contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40
41 /*
42  * Copyright (c) 1995, 1996, 1997 Carnegie-Mellon University.
43  * All rights reserved.
44  *
45  * Author: Chris G. Demetriou
46  * 
47  * Permission to use, copy, modify and distribute this software and
48  * its documentation is hereby granted, provided that both the copyright
49  * notice and this permission notice appear in all copies of the
50  * software, derivative works or modified versions, and any portions
51  * thereof, and that both notices appear in supporting documentation.
52  * 
53  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 
54  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 
55  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
56  * 
57  * Carnegie Mellon requests users of this software to return to
58  *
59  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
60  *  School of Computer Science
61  *  Carnegie Mellon University
62  *  Pittsburgh PA 15213-3890
63  *
64  * any improvements or extensions that they make and grant Carnegie the
65  * rights to redistribute these changes.
66  */
67 /*
68  * Additional Copyright (c) 1997 by Matthew Jacob for NASA/Ames Research Center
69  */
70 /*
71  * Additional Copyright (c) 1999 by Andrew Gallatin 
72  *
73  * $FreeBSD$
74  */
75
76 #include "opt_ddb.h"
77
78 #include <sys/param.h>
79 #include <sys/systm.h>
80 #include <sys/termios.h>
81
82 #include <machine/rpb.h>
83 #include <machine/cpuconf.h>
84 #include <machine/clock.h>
85
86 #include <alpha/pci/apecsvar.h>
87 #include <alpha/pci/ciavar.h>
88
89 #include <pci/pcivar.h>
90
91
92 #include "sio.h"
93 #include "sc.h"
94
95 #ifndef CONSPEED
96 #define CONSPEED TTYDEF_SPEED
97 #endif
98 static int comcnrate = CONSPEED;
99
100 void dec_1000a_init __P((int));
101 static void dec_1000a_cons_init __P((void));
102
103
104 static void dec_1000_intr_map __P((void *));
105 static void dec_1000_intr_disable __P((int));
106 static void dec_1000_intr_enable __P((int));
107 static void dec_1000_intr_init __P((void));
108
109 static void dec_1000a_intr_map __P((void *));
110 static void dec_1000a_intr_disable __P((int));
111 static void dec_1000a_intr_enable __P((int));
112 static void dec_1000a_intr_init __P((void));
113
114 extern int siocnattach __P((int, int));
115 extern int siogdbattach __P((int, int));
116 extern int sccnattach __P((void));
117
118
119 static const struct alpha_variation_table dec_1000_variations[] = {
120         { 0, "AlphaServer 1000" },
121         { 0, NULL },
122 };
123
124 static const struct alpha_variation_table dec_1000a_variations[] = {
125         { 0, "AlphaServer 1000A" },
126         { 0, NULL },
127 };
128
129 void
130 dec_1000a_init(int cputype)
131 {
132         u_int64_t variation;
133
134         platform.family = "AlphaServer 1000/1000A";
135
136         if ((platform.model = alpha_dsr_sysname()) == NULL) {
137                 variation = hwrpb->rpb_variation & SV_ST_MASK;
138                 if ((platform.model = alpha_variation_name(variation,
139                     cputype == ST_DEC_1000 ? dec_1000_variations
140                                            : dec_1000a_variations)) == NULL)
141                         platform.model = alpha_unknown_sysname();
142         }
143
144         switch(LOCATE_PCS(hwrpb, 0)->pcs_proc_type & PCS_PROC_MAJOR) {
145         case PCS_PROC_EV4:
146         case PCS_PROC_EV45:
147                 platform.iobus = "apecs";
148                 platform.pci_intr_map = dec_1000_intr_map;
149                 platform.pci_intr_disable = dec_1000_intr_disable;
150                 platform.pci_intr_enable = dec_1000_intr_enable;
151                 platform.pci_intr_init = dec_1000_intr_init;
152                 break;
153
154         default:
155                 platform.iobus = "cia";
156                 platform.pci_intr_map = dec_1000a_intr_map;
157                 platform.pci_intr_disable = dec_1000a_intr_disable;
158                 platform.pci_intr_enable = dec_1000a_intr_enable;
159                 platform.pci_intr_init = dec_1000a_intr_init;
160                 break;
161         }
162         platform.cons_init = dec_1000a_cons_init;
163 }
164
165 extern int comconsole; /* XXX for forcing comconsole when srm serial console is used */
166 static void
167 dec_1000a_cons_init()
168 {
169         struct ctb *ctb;
170
171         if(strcmp(platform.iobus, "cia") == 0) {
172                 cia_init();
173         } else {
174                 apecs_init();
175         }
176
177 #ifdef DDB
178         siogdbattach(0x2f8, 57600);
179 #endif
180
181         ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off);
182
183         switch (ctb->ctb_term_type) {
184         case 2: 
185                 /* serial console ... */
186                 /* XXX */
187                 {
188                         /*
189                          * Delay to allow PROM putchars to complete.
190                          * FIFO depth * character time,
191                          * character time = (1000000 / (defaultrate / 10))
192                          */
193                         DELAY(160000000 / comcnrate);
194
195                         /* 
196                          * force a comconsole on com1 if the SRM has a serial
197                          * console
198                          */
199                         comconsole = 0;
200                         if (siocnattach(0x3f8, comcnrate))
201                                 panic("can't init serial console");
202
203                         break;
204                 }
205
206         case 3:
207                 /* display console ... */
208                 /* XXX */
209 #if NSC > 0
210                 sccnattach();
211 #else
212                 panic("not configured to use display && keyboard console");
213 #endif
214                 break;
215
216         default:
217                 printf("ctb->ctb_term_type = 0x%lx\n", ctb->ctb_term_type);
218                 printf("ctb->ctb_turboslot = 0x%lx\n", ctb->ctb_turboslot);
219
220                 panic("consinit: unknown console type %d\n",
221                     (int) ctb->ctb_term_type);
222         }
223 }
224
225
226 static void
227 dec_1000_intr_map(arg)
228         void *arg;
229 {
230         pcicfgregs *cfg = (pcicfgregs *)arg;
231
232         if (cfg->intpin == 0)   /* No IRQ used. */
233                 return;
234         if (!(1 <= cfg->intpin && cfg->intpin <= 4))
235                 goto bad;
236
237         switch(cfg->slot) {
238         case 6:
239                 if(cfg->intpin != 1)
240                         break;
241                 cfg->intline = 0xc;             /* integrated ncr scsi */
242                 return;
243                 break;
244         case 11:
245         case 12:
246         case 13:
247                 cfg->intline = (cfg->slot - 11) * 4 + cfg->intpin - 1;
248                 return;
249                 break;
250         }
251 bad:    printf("dec_1000_intr_map: can't map dev %d pin %d\n",
252                 cfg->slot, cfg->intpin);
253 }
254
255
256 /*
257  * Read and write the mystery ICU IMR registers
258  * on the AlphaServer 1000
259  */
260
261 #define IR()    inw(0x536)
262 #define IW(x)   outw(0x536, (x))
263
264 /*
265  * Enable and disable interrupts at the ICU level
266  */
267
268 static void
269 dec_1000_intr_enable(irq)
270         int irq;
271 {
272         IW(IR() | 1 << irq);
273 }
274
275 static void
276 dec_1000_intr_disable(irq)
277         int irq;
278 {
279         IW(IR() & ~(1 << irq));
280 }
281
282
283 static void
284 dec_1000_intr_init()
285 {
286 /*
287  * Initialize mystery ICU
288  */
289         IW(0);                                  /* XXX ?? */    
290 /*
291  * Enable cascade interrupt.
292  */
293         dec_1000_intr_enable(2);
294 }
295
296 /*
297  * Read and write the mystery ICU IMR registers
298  * on the AlphaServer 1000a
299  */
300
301 #define IRA(o)          inw(0x54a + 2*(o))
302 #define IWA(o, v)       outw(0x54a + 2*(o), (v))
303 #define IMR2IRQ(bn)     ((bn) - 1)
304 #define IRQ2IMR(irq)    ((irq) + 1)
305
306 static void 
307 dec_1000a_intr_map(arg)
308         void *arg;
309 {
310         pcicfgregs *cfg = (pcicfgregs *)arg;
311         int device = cfg->slot;
312         int imrbit;
313         /*
314          * Get bit number in mystery ICU imr
315          */
316         static const signed char imrmap[][4] = {
317 #               define  IRQSPLIT(o) { (o), (o)+1, (o)+16, (o)+16+1 }
318 #               define  IRQNONE          { 0, 0, 0, 0 }
319                 /*  0  */ { 1, 0, 0, 0 },       /* Noritake and Pintake */
320                 /*  1  */ IRQSPLIT(8),
321                 /*  2  */ IRQSPLIT(10),
322                 /*  3  */ IRQSPLIT(12),
323                 /*  4  */ IRQSPLIT(14),
324                 /*  5  */ { 1, 0, 0, 0 },       /* Corelle */
325                 /*  6  */ { 10, 0, 0, 0 },      /* Corelle */
326                 /*  7  */ IRQNONE,
327                 /*  8  */ { 1, 0, 0, 0 },       /* isp behind ppb */
328                 /*  9  */ IRQNONE,
329                 /* 10  */ IRQNONE,
330                 /* 11  */ IRQSPLIT(2),
331                 /* 12  */ IRQSPLIT(4),
332                 /* 13  */ IRQSPLIT(6),
333                 /* 14  */ IRQSPLIT(8)           /* Corelle */
334         };
335
336         if (cfg->intpin == 0)   /* No IRQ used. */
337                 return;
338         if (!(1 <= cfg->intpin && cfg->intpin <= 4))
339                 goto bad;
340
341         if (0 <= device && device < sizeof imrmap / sizeof imrmap[0]) {
342                 imrbit = imrmap[device][cfg->intpin - 1];
343                 if (imrbit) {
344                         cfg->intline = IMR2IRQ(imrbit);
345                         return;
346                 }
347         }
348 bad:    printf("dec_1000a_intr_map: can't map dev %d pin %d\n", device, cfg->intpin);
349 }
350
351
352
353
354 static void
355 dec_1000a_intr_enable(irq)
356         int irq;
357 {
358         int imrval = IRQ2IMR(irq);
359         int i = imrval >= 16;
360
361         IWA(i, IRA(i) | 1 << (imrval & 0xf));
362 }
363
364
365
366 static void 
367 dec_1000a_intr_disable(irq)
368         int irq;
369 {
370         int imrval = IRQ2IMR(irq);
371         int i = imrval >= 16;
372
373         IWA(i, IRA(i) & ~(1 << (imrval & 0xf)));
374 }
375
376 static void
377 dec_1000a_intr_init()
378 {
379
380 /*
381  * Initialize mystery ICU
382  */
383
384         IWA(0, IRA(0) & 1);
385         IWA(1, IRA(0) & 3);
386 /*
387  * Enable cascade interrupt.
388  */     
389         dec_1000_intr_enable(2);
390 }
391