Annotation of sys/arch/i386/pci/piix.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: piix.c,v 1.8 2006/09/19 11:06:34 jsg Exp $ */
2: /* $NetBSD: piix.c,v 1.1 1999/11/17 01:21:20 thorpej Exp $ */
3:
4: /*-
5: * Copyright (c) 1999 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) 1999, by UCHIYAMA Yasushi
43: * All rights reserved.
44: *
45: * Redistribution and use in source and binary forms, with or without
46: * modification, are permitted provided that the following conditions
47: * are met:
48: * 1. Redistributions of source code must retain the above copyright
49: * notice, this list of conditions and the following disclaimer.
50: * 2. The name of the developer may NOT be used to endorse or promote products
51: * derived from this software without specific prior written permission.
52: *
53: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
54: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
57: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63: * SUCH DAMAGE.
64: */
65:
66: /*
67: * Support for the Intel PIIX PCI-ISA bridge interrupt controller.
68: */
69:
70: #include <sys/param.h>
71: #include <sys/systm.h>
72: #include <sys/device.h>
73: #include <sys/malloc.h>
74:
75: #include <machine/intr.h>
76: #include <machine/bus.h>
77:
78: #include <dev/pci/pcivar.h>
79: #include <dev/pci/pcireg.h>
80: #include <dev/pci/pcidevs.h>
81:
82: #include <i386/pci/pcibiosvar.h>
83: #include <i386/pci/piixreg.h>
84: #include <i386/pci/piixvar.h>
85:
86: #ifdef PIIX_DEBUG
87: #define DPRINTF(arg) printf arg
88: #else
89: #define DPRINTF(arg)
90: #endif
91:
92: int piix_getclink(pciintr_icu_handle_t, int, int *);
93: int piix_get_intr(pciintr_icu_handle_t, int, int *);
94: int piix_set_intr(pciintr_icu_handle_t, int, int);
95: #ifdef PIIX_DEBUG
96: void piix_pir_dump(struct piix_handle *);
97: #endif
98:
99: const struct pciintr_icu piix_pci_icu = {
100: piix_getclink,
101: piix_get_intr,
102: piix_set_intr,
103: piix_get_trigger,
104: piix_set_trigger,
105: };
106:
107: int
108: piix_init(pci_chipset_tag_t pc, bus_space_tag_t iot, pcitag_t tag,
109: pciintr_icu_tag_t *ptagp, pciintr_icu_handle_t *phandp)
110: {
111: struct piix_handle *ph;
112:
113: ph = malloc(sizeof(*ph), M_DEVBUF, M_NOWAIT);
114: if (ph == NULL)
115: return (1);
116:
117: ph->ph_iot = iot;
118: ph->ph_pc = pc;
119: ph->ph_tag = tag;
120:
121: if (bus_space_map(iot, PIIX_REG_ELCR, PIIX_REG_ELCR_SIZE, 0,
122: &ph->ph_elcr_ioh) != 0) {
123: free(ph, M_DEVBUF);
124: return (1);
125: }
126:
127: #ifdef PIIX_DEBUG
128: piix_pir_dump(ph);
129: #endif
130: *ptagp = &piix_pci_icu;
131: *phandp = ph;
132: return (0);
133: }
134:
135: int
136: piix_getclink(pciintr_icu_handle_t v, int link, int *clinkp)
137: {
138: DPRINTF(("PIIX link value 0x%x: ", link));
139:
140: /* Pattern 1: simple. */
141: if (PIIX_LEGAL_LINK(link - 1)) {
142: *clinkp = link - 1;
143: DPRINTF(("PIRQ %d (simple)\n", *clinkp));
144: return (0);
145: }
146:
147: /* Pattern 2: configuration register offset */
148: if (link >= 0x60 && link <= 0x63) {
149: *clinkp = link - 0x60;
150: DPRINTF(("PIRQ %d (register offset)\n", *clinkp));
151: return (0);
152: }
153:
154: /* Pattern 3: configuration register offset, PIRQE# - PIRQH# */
155: if (link >= 0x68 && link <= 0x6b) {
156: *clinkp = link - 0x64;
157: DPRINTF(("PIRQ %d (high register offset)\n", *clinkp));
158: return (0);
159: }
160:
161: DPRINTF(("bogus IRQ selection source\n"));
162: return (1);
163: }
164:
165: int
166: piix_get_intr(pciintr_icu_handle_t v, int clink, int *irqp)
167: {
168: struct piix_handle *ph = v;
169: int shift, off;
170: pcireg_t reg;
171:
172: if (PIIX_LEGAL_LINK(clink) == 0)
173: return (1);
174:
175: off = PIIX_CFG_PIRQ;
176: if (clink > 3) {
177: off += 8;
178: clink -= 4;
179: }
180:
181: reg = pci_conf_read(ph->ph_pc, ph->ph_tag, off);
182: shift = clink << 3;
183: if ((reg >> shift) & PIIX_CFG_PIRQ_NONE)
184: *irqp = I386_PCI_INTERRUPT_LINE_NO_CONNECTION;
185: else
186: *irqp = PIIX_PIRQ(reg, clink);
187:
188: return (0);
189: }
190:
191: int
192: piix_set_intr(pciintr_icu_handle_t v, int clink, int irq)
193: {
194: struct piix_handle *ph = v;
195: int shift, off;
196: pcireg_t reg;
197:
198: if (PIIX_LEGAL_LINK(clink) == 0 || PIIX_LEGAL_IRQ(irq) == 0)
199: return (1);
200:
201: off = PIIX_CFG_PIRQ;
202: if (clink > 3) {
203: off += 8;
204: clink -= 4;
205: }
206:
207: reg = pci_conf_read(ph->ph_pc, ph->ph_tag, off);
208: shift = clink << 3;
209: reg &= ~((PIIX_CFG_PIRQ_NONE | PIIX_CFG_PIRQ_MASK) << shift);
210: reg |= irq << shift;
211: pci_conf_write(ph->ph_pc, ph->ph_tag, off, reg);
212:
213: return (0);
214: }
215:
216: int
217: piix_get_trigger(pciintr_icu_handle_t v, int irq, int *triggerp)
218: {
219: struct piix_handle *ph = v;
220: int off, bit;
221: u_int8_t elcr;
222:
223: if (PIIX_LEGAL_IRQ(irq) == 0)
224: return (1);
225:
226: off = (irq > 7) ? 1 : 0;
227: bit = irq & 7;
228:
229: elcr = bus_space_read_1(ph->ph_iot, ph->ph_elcr_ioh, off);
230: if (elcr & (1 << bit))
231: *triggerp = IST_LEVEL;
232: else
233: *triggerp = IST_EDGE;
234:
235: return (0);
236: }
237:
238: int
239: piix_set_trigger(pciintr_icu_handle_t v, int irq, int trigger)
240: {
241: struct piix_handle *ph = v;
242: int off, bit;
243: u_int8_t elcr;
244:
245: if (PIIX_LEGAL_IRQ(irq) == 0)
246: return (1);
247:
248: off = (irq > 7) ? 1 : 0;
249: bit = irq & 7;
250:
251: elcr = bus_space_read_1(ph->ph_iot, ph->ph_elcr_ioh, off);
252: if (trigger == IST_LEVEL)
253: elcr |= (1 << bit);
254: else
255: elcr &= ~(1 << bit);
256: bus_space_write_1(ph->ph_iot, ph->ph_elcr_ioh, off, elcr);
257:
258: return (0);
259: }
260:
261: #ifdef PIIX_DEBUG
262: void
263: piix_pir_dump(struct piix_handle *ph)
264: {
265: int i, irq;
266: pcireg_t irqs = pci_conf_read(ph->ph_pc, ph->ph_tag, PIIX_CFG_PIRQ);
267: u_int8_t elcr[2];
268:
269: elcr[0] = bus_space_read_1(ph->ph_iot, ph->ph_elcr_ioh, 0);
270: elcr[1] = bus_space_read_1(ph->ph_iot, ph->ph_elcr_ioh, 1);
271:
272: for (i = 0; i < 8; i++) {
273: if (i == 4)
274: irqs = pci_conf_read(ph->ph_pc, ph->ph_tag,
275: PIIX_CFG_PIRQH);
276:
277: irq = PIIX_PIRQ(irqs, i);
278: if (irq & PIIX_CFG_PIRQ_NONE)
279: printf("PIIX PIRQ %d: irq none (0x%x)\n", i, irq);
280: else
281: printf("PIIX PIRQ %d: irq %d\n", i, irq);
282: }
283:
284: printf("PIIX irq:");
285: for (i = 0; i < 16; i++)
286: printf(" %2d", i);
287: printf("\n");
288: printf(" trigger:");
289: for (i = 0; i < 16; i++)
290: printf(" %c", (elcr[(i & 8) ? 1 : 0] & (1 << (i & 7))) ?
291: 'L' : 'E');
292: printf("\n");
293: }
294: #endif /* PIIX_DEBUG */
CVSweb