Annotation of sys/arch/alpha/pci/pci_kn20aa.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: pci_kn20aa.c,v 1.22 2006/06/15 20:08:29 brad Exp $ */
2: /* $NetBSD: pci_kn20aa.c,v 1.21 1996/11/17 02:05:27 cgd Exp $ */
3:
4: /*
5: * Copyright (c) 1995, 1996 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: #include <sys/types.h>
32: #include <sys/param.h>
33: #include <sys/time.h>
34: #include <sys/systm.h>
35: #include <sys/errno.h>
36: #include <sys/malloc.h>
37: #include <sys/device.h>
38: #include <sys/syslog.h>
39:
40: #include <uvm/uvm_extern.h>
41:
42: #include <machine/autoconf.h>
43:
44: #include <dev/pci/pcireg.h>
45: #include <dev/pci/pcivar.h>
46:
47: #include <alpha/pci/ciareg.h>
48: #include <alpha/pci/ciavar.h>
49:
50: #include <alpha/pci/pci_kn20aa.h>
51:
52: #include "sio.h"
53: #if NSIO
54: #include <alpha/pci/siovar.h>
55: #endif
56:
57: int dec_kn20aa_intr_map(void *, pcitag_t, int, int,
58: pci_intr_handle_t *);
59: const char *dec_kn20aa_intr_string(void *, pci_intr_handle_t);
60: int dec_kn20aa_intr_line(void *, pci_intr_handle_t);
61: void *dec_kn20aa_intr_establish(void *, pci_intr_handle_t,
62: int, int (*func)(void *), void *, char *);
63: void dec_kn20aa_intr_disestablish(void *, void *);
64:
65: #define KN20AA_PCEB_IRQ 31
66: #define KN20AA_MAX_IRQ 32
67: #define PCI_STRAY_MAX 5
68:
69: struct alpha_shared_intr *kn20aa_pci_intr;
70: struct evcount kn20aa_intr_count;
71:
72: void kn20aa_iointr(void *arg, unsigned long vec);
73: void kn20aa_enable_intr(int irq);
74: void kn20aa_disable_intr(int irq);
75:
76: void
77: pci_kn20aa_pickintr(ccp)
78: struct cia_config *ccp;
79: {
80: int i;
81: bus_space_tag_t iot = &ccp->cc_iot;
82: pci_chipset_tag_t pc = &ccp->cc_pc;
83:
84: pc->pc_intr_v = ccp;
85: pc->pc_intr_map = dec_kn20aa_intr_map;
86: pc->pc_intr_string = dec_kn20aa_intr_string;
87: pc->pc_intr_line = dec_kn20aa_intr_line;
88: pc->pc_intr_establish = dec_kn20aa_intr_establish;
89: pc->pc_intr_disestablish = dec_kn20aa_intr_disestablish;
90:
91: /* Not supported on KN20AA. */
92: pc->pc_pciide_compat_intr_establish = NULL;
93: pc->pc_pciide_compat_intr_disestablish = NULL;
94:
95: kn20aa_pci_intr = alpha_shared_intr_alloc(KN20AA_MAX_IRQ);
96: for (i = 0; i < KN20AA_MAX_IRQ; i++)
97: alpha_shared_intr_set_maxstrays(kn20aa_pci_intr, i,
98: PCI_STRAY_MAX);
99:
100: #if NSIO
101: sio_intr_setup(pc, iot);
102: kn20aa_enable_intr(KN20AA_PCEB_IRQ);
103: #endif
104: }
105:
106: int
107: dec_kn20aa_intr_map(ccv, bustag, buspin, line, ihp)
108: void *ccv;
109: pcitag_t bustag;
110: int buspin, line;
111: pci_intr_handle_t *ihp;
112: {
113: struct cia_config *ccp = ccv;
114: pci_chipset_tag_t pc = &ccp->cc_pc;
115: int device;
116: int kn20aa_irq;
117:
118: if (buspin == 0) {
119: /* No IRQ used. */
120: return 1;
121: }
122: if (buspin > 4) {
123: printf("pci_map_int: bad interrupt pin %d\n", buspin);
124: return 1;
125: }
126:
127: /*
128: * Slot->interrupt translation. Appears to work, though it
129: * may not hold up forever.
130: *
131: * The DEC engineers who did this hardware obviously engaged
132: * in random drug testing.
133: */
134: pci_decompose_tag(pc, bustag, NULL, &device, NULL);
135: switch (device) {
136: case 11:
137: case 12:
138: kn20aa_irq = ((device - 11) + 0) * 4;
139: break;
140:
141: case 7:
142: kn20aa_irq = 8;
143: break;
144:
145: case 9:
146: kn20aa_irq = 12;
147: break;
148:
149: case 6: /* 21040 on AlphaStation 500 */
150: kn20aa_irq = 13;
151: break;
152:
153: case 8:
154: kn20aa_irq = 16;
155: break;
156:
157: default:
158: printf("dec_kn20aa_intr_map: weird device number %d\n",
159: device);
160: return 1;
161: }
162:
163: kn20aa_irq += buspin - 1;
164: if (kn20aa_irq > KN20AA_MAX_IRQ)
165: panic("pci_kn20aa_map_int: kn20aa_irq too large (%d)",
166: kn20aa_irq);
167:
168: *ihp = kn20aa_irq;
169: return (0);
170: }
171:
172: const char *
173: dec_kn20aa_intr_string(ccv, ih)
174: void *ccv;
175: pci_intr_handle_t ih;
176: {
177: static char irqstr[15]; /* 11 + 2 + NULL + sanity */
178:
179: if (ih > KN20AA_MAX_IRQ)
180: panic("dec_kn20aa_intr_string: bogus kn20aa IRQ 0x%x", ih);
181:
182: snprintf(irqstr, sizeof irqstr, "kn20aa irq %ld", ih);
183: return (irqstr);
184: }
185:
186: int
187: dec_kn20aa_intr_line(ccv, ih)
188: void *ccv;
189: pci_intr_handle_t ih;
190: {
191: return (ih);
192: }
193:
194: void *
195: dec_kn20aa_intr_establish(ccv, ih, level, func, arg, name)
196: void *ccv, *arg;
197: pci_intr_handle_t ih;
198: int level;
199: int (*func)(void *);
200: char *name;
201: {
202: void *cookie;
203:
204: if (ih > KN20AA_MAX_IRQ)
205: panic("dec_kn20aa_intr_establish: bogus kn20aa IRQ 0x%x",
206: ih);
207:
208: cookie = alpha_shared_intr_establish(kn20aa_pci_intr, ih, IST_LEVEL,
209: level, func, arg, name);
210:
211: if (cookie != NULL &&
212: alpha_shared_intr_firstactive(kn20aa_pci_intr, ih)) {
213: scb_set(0x900 + SCB_IDXTOVEC(ih), kn20aa_iointr, NULL);
214: kn20aa_enable_intr(ih);
215: }
216: return (cookie);
217: }
218:
219: void
220: dec_kn20aa_intr_disestablish(ccv, cookie)
221: void *ccv, *cookie;
222: {
223: struct alpha_shared_intrhand *ih = cookie;
224: unsigned int irq = ih->ih_num;
225: int s;
226:
227: s = splhigh();
228:
229: alpha_shared_intr_disestablish(kn20aa_pci_intr, cookie,
230: "kn20aa irq");
231: if (alpha_shared_intr_isactive(kn20aa_pci_intr, irq) == 0) {
232: kn20aa_disable_intr(irq);
233: alpha_shared_intr_set_dfltsharetype(kn20aa_pci_intr, irq,
234: IST_NONE);
235: scb_free(0x900 + SCB_IDXTOVEC(irq));
236: }
237: splx(s);
238: }
239:
240: void
241: kn20aa_iointr(arg, vec)
242: void *arg;
243: unsigned long vec;
244: {
245: int irq;
246:
247: irq = SCB_VECTOIDX(vec - 0x900);
248:
249: if (!alpha_shared_intr_dispatch(kn20aa_pci_intr, irq)) {
250: alpha_shared_intr_stray(kn20aa_pci_intr, irq,
251: "kn20aa irq");
252: if (ALPHA_SHARED_INTR_DISABLE(kn20aa_pci_intr, irq))
253: kn20aa_disable_intr(irq);
254: } else
255: alpha_shared_intr_reset_strays(kn20aa_pci_intr, irq);
256: }
257:
258: void
259: kn20aa_enable_intr(irq)
260: int irq;
261: {
262:
263: /*
264: * From disassembling small bits of the OSF/1 kernel:
265: * the following appears to enable a given interrupt request.
266: * "blech." I'd give valuable body parts for better docs or
267: * for a good decompiler.
268: */
269: alpha_mb();
270: REGVAL(0x8780000000L + 0x40L) |= (1 << irq); /* XXX */
271: alpha_mb();
272: }
273:
274: void
275: kn20aa_disable_intr(irq)
276: int irq;
277: {
278:
279: alpha_mb();
280: REGVAL(0x8780000000L + 0x40L) &= ~(1 << irq); /* XXX */
281: alpha_mb();
282: }
CVSweb