Annotation of sys/arch/alpha/pci/pci_eb164.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: pci_eb164.c,v 1.20 2007/05/02 21:50:14 martin Exp $ */
2: /* $NetBSD: pci_eb164.c,v 1.27 2000/06/06 00:50:15 thorpej Exp $ */
3:
4: /*-
5: * Copyright (c) 1998 The NetBSD Foundation, Inc.
6: * All rights reserved.
7: *
8: * This code is derived from software contributed to The NetBSD Foundation
9: * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10: * NASA Ames Research Center.
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 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: #include <sys/types.h>
69: #include <sys/param.h>
70: #include <sys/time.h>
71: #include <sys/systm.h>
72: #include <sys/errno.h>
73: #include <sys/malloc.h>
74: #include <sys/device.h>
75: #include <sys/syslog.h>
76:
77: #include <uvm/uvm.h>
78:
79: #include <machine/autoconf.h>
80: #include <machine/rpb.h>
81:
82: #include <dev/pci/pcireg.h>
83: #include <dev/pci/pcivar.h>
84: #include <dev/pci/pciidereg.h>
85: #include <dev/pci/pciidevar.h>
86:
87: #include <alpha/pci/ciareg.h>
88: #include <alpha/pci/ciavar.h>
89:
90: #include <alpha/pci/pci_eb164.h>
91:
92: #include "sio.h"
93: #if NSIO
94: #include <alpha/pci/siovar.h>
95: #endif
96:
97: int dec_eb164_intr_map(void *, pcitag_t, int, int,
98: pci_intr_handle_t *);
99: const char *dec_eb164_intr_string(void *, pci_intr_handle_t);
100: int dec_eb164_intr_line(void *, pci_intr_handle_t);
101: void *dec_eb164_intr_establish(void *, pci_intr_handle_t,
102: int, int (*func)(void *), void *, char *);
103: void dec_eb164_intr_disestablish(void *, void *);
104:
105: void *dec_eb164_pciide_compat_intr_establish(void *, struct device *,
106: struct pci_attach_args *, int, int (*)(void *), void *);
107: void dec_eb164_pciide_compat_intr_disestablish(void *, void *);
108:
109: #define EB164_SIO_IRQ 4
110: #define EB164_MAX_IRQ 24
111: #define PCI_STRAY_MAX 5
112:
113: struct alpha_shared_intr *eb164_pci_intr;
114:
115: bus_space_tag_t eb164_intrgate_iot;
116: bus_space_handle_t eb164_intrgate_ioh;
117:
118: void eb164_iointr(void *arg, unsigned long vec);
119: extern void eb164_intr_enable(int irq); /* pci_eb164_intr.S */
120: extern void eb164_intr_disable(int irq); /* pci_eb164_intr.S */
121:
122: void
123: pci_eb164_pickintr(ccp)
124: struct cia_config *ccp;
125: {
126: bus_space_tag_t iot = &ccp->cc_iot;
127: pci_chipset_tag_t pc = &ccp->cc_pc;
128: int i;
129:
130: pc->pc_intr_v = ccp;
131: pc->pc_intr_map = dec_eb164_intr_map;
132: pc->pc_intr_string = dec_eb164_intr_string;
133: pc->pc_intr_line = dec_eb164_intr_line;
134: pc->pc_intr_establish = dec_eb164_intr_establish;
135: pc->pc_intr_disestablish = dec_eb164_intr_disestablish;
136:
137: pc->pc_pciide_compat_intr_establish =
138: dec_eb164_pciide_compat_intr_establish;
139: pc->pc_pciide_compat_intr_disestablish =
140: dec_eb164_pciide_compat_intr_disestablish;
141:
142: eb164_intrgate_iot = iot;
143: if (bus_space_map(eb164_intrgate_iot, 0x804, 3, 0,
144: &eb164_intrgate_ioh) != 0)
145: panic("pci_eb164_pickintr: couldn't map interrupt PLD");
146: for (i = 0; i < EB164_MAX_IRQ; i++)
147: eb164_intr_disable(i);
148:
149: eb164_pci_intr = alpha_shared_intr_alloc(EB164_MAX_IRQ);
150: for (i = 0; i < EB164_MAX_IRQ; i++) {
151: /*
152: * Systems with a Pyxis seem to have problems with
153: * stray interrupts, so just ignore them. Sigh,
154: * I hate buggy hardware.
155: */
156: alpha_shared_intr_set_maxstrays(eb164_pci_intr, i,
157: (ccp->cc_flags & CCF_ISPYXIS) ? 0 : PCI_STRAY_MAX);
158: }
159:
160: #if NSIO
161: sio_intr_setup(pc, iot);
162: eb164_intr_enable(EB164_SIO_IRQ);
163: #endif
164: }
165:
166: int
167: dec_eb164_intr_map(ccv, bustag, buspin, line, ihp)
168: void *ccv;
169: pcitag_t bustag;
170: int buspin, line;
171: pci_intr_handle_t *ihp;
172: {
173: struct cia_config *ccp = ccv;
174: pci_chipset_tag_t pc = &ccp->cc_pc;
175: int bus, device, function;
176: u_int64_t variation;
177:
178: if (buspin == 0) {
179: /* No IRQ used. */
180: return 1;
181: }
182: if (buspin > 4) {
183: printf("dec_eb164_intr_map: bad interrupt pin %d\n", buspin);
184: return 1;
185: }
186:
187: pci_decompose_tag(pc, bustag, &bus, &device, &function);
188:
189: variation = hwrpb->rpb_variation & SV_ST_MASK;
190:
191: /*
192: *
193: * The AlphaPC 164 and AlphaPC 164LX have a CMD PCI IDE controller
194: * at bus 0 device 11. These are wired to compatibility mode,
195: * so do not map their interrupts.
196: *
197: * The AlphaPC 164SX has PCI IDE on functions 1 and 2 of the
198: * Cypress PCI-ISA bridge at bus 0 device 8. These, too, are
199: * wired to compatibility mode.
200: *
201: * Real EB164s have ISA IDE on the Super I/O chip.
202: */
203: if (bus == 0) {
204: if (variation >= SV_ST_ALPHAPC164_366 &&
205: variation <= SV_ST_ALPHAPC164LX_600) {
206: if (device == 8)
207: panic("dec_eb164_intr_map: SIO device");
208: if (device == 11)
209: return (1);
210: } else if (variation >= SV_ST_ALPHAPC164SX_400 &&
211: variation <= SV_ST_ALPHAPC164SX_600) {
212: if (device == 8) {
213: if (function == 0)
214: panic("dec_eb164_intr_map: SIO device");
215: return (1);
216: }
217: } else {
218: if (device == 8)
219: panic("dec_eb164_intr_map: SIO device");
220: }
221: }
222:
223: /*
224: * The console places the interrupt mapping in the "line" value.
225: * A value of (char)-1 indicates there is no mapping.
226: */
227: if (line == 0xff) {
228: printf("dec_eb164_intr_map: no mapping for %d/%d/%d\n",
229: bus, device, function);
230: return (1);
231: }
232:
233: if (line > EB164_MAX_IRQ)
234: panic("dec_eb164_intr_map: eb164 irq too large (%d)",
235: line);
236:
237: *ihp = line;
238: return (0);
239: }
240:
241: const char *
242: dec_eb164_intr_string(ccv, ih)
243: void *ccv;
244: pci_intr_handle_t ih;
245: {
246: #if 0
247: struct cia_config *ccp = ccv;
248: #endif
249: static char irqstr[15]; /* 11 + 2 + NULL + sanity */
250:
251: if (ih > EB164_MAX_IRQ)
252: panic("dec_eb164_intr_string: bogus eb164 IRQ 0x%lx", ih);
253: snprintf(irqstr, sizeof irqstr, "eb164 irq %ld", ih);
254: return (irqstr);
255: }
256:
257: int
258: dec_eb164_intr_line(ccv, ih)
259: void *ccv;
260: pci_intr_handle_t ih;
261: {
262: return (ih);
263: }
264:
265: void *
266: dec_eb164_intr_establish(ccv, ih, level, func, arg, name)
267: void *ccv, *arg;
268: pci_intr_handle_t ih;
269: int level;
270: int (*func)(void *);
271: char *name;
272: {
273: #if 0
274: struct cia_config *ccp = ccv;
275: #endif
276: void *cookie;
277:
278: if (ih > EB164_MAX_IRQ)
279: panic("dec_eb164_intr_establish: bogus eb164 IRQ 0x%lx", ih);
280:
281: cookie = alpha_shared_intr_establish(eb164_pci_intr, ih, IST_LEVEL,
282: level, func, arg, name);
283:
284: if (cookie != NULL &&
285: alpha_shared_intr_firstactive(eb164_pci_intr, ih)) {
286: scb_set(0x900 + SCB_IDXTOVEC(ih), eb164_iointr, NULL);
287: eb164_intr_enable(ih);
288: }
289: return (cookie);
290: }
291:
292: void
293: dec_eb164_intr_disestablish(ccv, cookie)
294: void *ccv, *cookie;
295: {
296: #if 0
297: struct cia_config *ccp = ccv;
298: #endif
299: struct alpha_shared_intrhand *ih = cookie;
300: unsigned int irq = ih->ih_num;
301: int s;
302:
303: s = splhigh();
304:
305: alpha_shared_intr_disestablish(eb164_pci_intr, cookie,
306: "eb164 irq");
307: if (alpha_shared_intr_isactive(eb164_pci_intr, irq) == 0) {
308: eb164_intr_disable(irq);
309: alpha_shared_intr_set_dfltsharetype(eb164_pci_intr, irq,
310: IST_NONE);
311: scb_free(0x900 + SCB_IDXTOVEC(irq));
312: }
313:
314: splx(s);
315: }
316:
317: void *
318: dec_eb164_pciide_compat_intr_establish(v, dev, pa, chan, func, arg)
319: void *v;
320: struct device *dev;
321: struct pci_attach_args *pa;
322: int chan;
323: int (*func)(void *);
324: void *arg;
325: {
326: pci_chipset_tag_t pc = pa->pa_pc;
327: void *cookie = NULL;
328: int bus, irq;
329:
330: pci_decompose_tag(pc, pa->pa_tag, &bus, NULL, NULL);
331:
332: /*
333: * If this isn't PCI bus #0, all bets are off.
334: */
335: if (bus != 0)
336: return (NULL);
337:
338: irq = PCIIDE_COMPAT_IRQ(chan);
339: #if NSIO
340: cookie = sio_intr_establish(NULL /*XXX*/, irq, IST_EDGE, IPL_BIO,
341: func, arg, dev->dv_xname);
342: if (cookie == NULL)
343: return (NULL);
344: #endif
345: return (cookie);
346: }
347:
348: void
349: dec_eb164_pciide_compat_intr_disestablish(void *v, void *cookie)
350: {
351: sio_intr_disestablish(NULL, cookie);
352: }
353:
354: void
355: eb164_iointr(arg, vec)
356: void *arg;
357: unsigned long vec;
358: {
359: int irq;
360:
361: irq = SCB_VECTOIDX(vec - 0x900);
362:
363: if (!alpha_shared_intr_dispatch(eb164_pci_intr, irq)) {
364: alpha_shared_intr_stray(eb164_pci_intr, irq,
365: "eb164 irq");
366: if (ALPHA_SHARED_INTR_DISABLE(eb164_pci_intr, irq))
367: eb164_intr_disable(irq);
368: } else
369: alpha_shared_intr_reset_strays(eb164_pci_intr, irq);
370: }
371:
372: #if 0 /* THIS DOES NOT WORK! see pci_eb164_intr.S. */
373: u_int8_t eb164_intr_mask[3] = { 0xff, 0xff, 0xff };
374:
375: void
376: eb164_intr_enable(irq)
377: int irq;
378: {
379: int byte = (irq / 8), bit = (irq % 8);
380:
381: #if 1
382: printf("eb164_intr_enable: enabling %d (%d:%d)\n", irq, byte, bit);
383: #endif
384: eb164_intr_mask[byte] &= ~(1 << bit);
385:
386: bus_space_write_1(eb164_intrgate_iot, eb164_intrgate_ioh, byte,
387: eb164_intr_mask[byte]);
388: }
389:
390: void
391: eb164_intr_disable(irq)
392: int irq;
393: {
394: int byte = (irq / 8), bit = (irq % 8);
395:
396: #if 1
397: printf("eb164_intr_disable: disabling %d (%d:%d)\n", irq, byte, bit);
398: #endif
399: eb164_intr_mask[byte] |= (1 << bit);
400:
401: bus_space_write_1(eb164_intrgate_iot, eb164_intrgate_ioh, byte,
402: eb164_intr_mask[byte]);
403: }
404: #endif
CVSweb