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