bandit.c revision 1.5 1 1.5 tsubai /* $NetBSD: bandit.c,v 1.5 1998/10/15 14:39:53 tsubai Exp $ */
2 1.1 tsubai
3 1.1 tsubai /*
4 1.3 tsubai * Copyright 1991-1998 by Open Software Foundation, Inc.
5 1.1 tsubai * All Rights Reserved
6 1.1 tsubai *
7 1.1 tsubai * Permission to use, copy, modify, and distribute this software and
8 1.1 tsubai * its documentation for any purpose and without fee is hereby granted,
9 1.1 tsubai * provided that the above copyright notice appears in all copies and
10 1.1 tsubai * that both the copyright notice and this permission notice appear in
11 1.1 tsubai * supporting documentation.
12 1.1 tsubai *
13 1.1 tsubai * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
14 1.1 tsubai * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
15 1.1 tsubai * FOR A PARTICULAR PURPOSE.
16 1.1 tsubai *
17 1.1 tsubai * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
18 1.1 tsubai * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
19 1.1 tsubai * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
20 1.1 tsubai * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21 1.1 tsubai * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 1.1 tsubai */
23 1.1 tsubai /*
24 1.3 tsubai * Copyright 1991-1998 by Apple Computer, Inc.
25 1.1 tsubai * All Rights Reserved
26 1.1 tsubai *
27 1.1 tsubai * Permission to use, copy, modify, and distribute this software and
28 1.1 tsubai * its documentation for any purpose and without fee is hereby granted,
29 1.1 tsubai * provided that the above copyright notice appears in all copies and
30 1.1 tsubai * that both the copyright notice and this permission notice appear in
31 1.1 tsubai * supporting documentation.
32 1.1 tsubai *
33 1.1 tsubai * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
34 1.1 tsubai * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
35 1.1 tsubai * FOR A PARTICULAR PURPOSE.
36 1.1 tsubai *
37 1.1 tsubai * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
38 1.1 tsubai * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
39 1.1 tsubai * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
40 1.1 tsubai * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
41 1.1 tsubai * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
42 1.1 tsubai */
43 1.1 tsubai
44 1.1 tsubai #include <sys/param.h>
45 1.1 tsubai #include <sys/device.h>
46 1.5 tsubai #include <sys/systm.h>
47 1.1 tsubai
48 1.1 tsubai #include <dev/pci/pcireg.h>
49 1.1 tsubai #include <dev/pci/pcivar.h>
50 1.1 tsubai #include <dev/ofw/openfirm.h>
51 1.1 tsubai
52 1.1 tsubai #include <machine/bus.h>
53 1.1 tsubai
54 1.1 tsubai #define PCI_BANDIT 11
55 1.1 tsubai
56 1.1 tsubai #define PCI_REG_BANDIT_CFG 0x40
57 1.1 tsubai #define PCI_REG_ADDR_MASK 0x48
58 1.1 tsubai #define PCI_REG_MODE_SELECT 0x50
59 1.1 tsubai #define PCI_REG_ARBUS_HOLDOFF 0x58
60 1.1 tsubai
61 1.1 tsubai #define PCI_MS_BYTESWAP 0x001 /* Enable Big Endian mode. (R/W)*/
62 1.1 tsubai #define PCI_MS_PASSATOMIC 0x002 /* PCI Bus to ARBus Lock are always allowed (R)*/
63 1.1 tsubai #define PCI_MS_NUMBER_MASK 0x00C /* PCI Bus Number (R) */
64 1.1 tsubai #define PCI_MS_IS_SYNC 0x010 /* Is Synchronous (1) or Async (0) ? (R)*/
65 1.1 tsubai #define PCI_MS_VGA_SPACE 0x020 /* Map VGA I/O space (R/W) */
66 1.1 tsubai #define PCI_MS_IO_COHERENT 0x040 /* I/O Coherent (R/W) */
67 1.1 tsubai #define PCI_MS_INT_ENABLE 0x080 /* Allow TEA or PCI Abort INT to pass to Grand Central (R/W) */
68 1.1 tsubai
69 1.3 tsubai #define BANDIT_SPECIAL_CYCLE 0xe00000 /* Special Cycle offset */
70 1.3 tsubai
71 1.1 tsubai static void bandit_init __P((pci_chipset_tag_t));
72 1.1 tsubai static void scan_pci_devs __P((void));
73 1.3 tsubai static void config_slot __P((int, pci_chipset_tag_t));
74 1.1 tsubai
75 1.1 tsubai void
76 1.1 tsubai pci_init()
77 1.1 tsubai {
78 1.1 tsubai scan_pci_devs();
79 1.1 tsubai }
80 1.1 tsubai
81 1.1 tsubai void
82 1.1 tsubai bandit_init(pc)
83 1.1 tsubai pci_chipset_tag_t pc;
84 1.1 tsubai {
85 1.1 tsubai u_int status;
86 1.1 tsubai pcitag_t tag;
87 1.1 tsubai
88 1.1 tsubai tag = pci_make_tag(pc, 0, PCI_BANDIT, 0);
89 1.1 tsubai if ((pci_conf_read(pc, tag, PCI_ID_REG) & 0xffff) == 0xffff)
90 1.1 tsubai return;
91 1.1 tsubai
92 1.1 tsubai status = pci_conf_read(pc, tag, PCI_REG_MODE_SELECT);
93 1.1 tsubai
94 1.1 tsubai if ((status & PCI_MS_IO_COHERENT) == 0) {
95 1.1 tsubai status |= PCI_MS_IO_COHERENT;
96 1.1 tsubai pci_conf_write(pc, tag, PCI_REG_MODE_SELECT, status);
97 1.1 tsubai }
98 1.1 tsubai
99 1.1 tsubai return;
100 1.1 tsubai }
101 1.1 tsubai
102 1.1 tsubai
103 1.1 tsubai void
104 1.1 tsubai scan_pci_devs()
105 1.1 tsubai {
106 1.1 tsubai int node;
107 1.1 tsubai char name[64];
108 1.1 tsubai int n = 0;
109 1.1 tsubai u_int reg[2];
110 1.1 tsubai
111 1.2 tsubai bzero(pci_bridges, sizeof(pci_bridges));
112 1.1 tsubai
113 1.1 tsubai node = OF_peer(0);
114 1.1 tsubai node = OF_child(node);
115 1.1 tsubai
116 1.1 tsubai while (node) {
117 1.1 tsubai if (OF_getprop(node, "name", name, sizeof(name)) <= 0)
118 1.1 tsubai continue;
119 1.3 tsubai if (strcmp(name, "bandit") == 0 ||
120 1.3 tsubai strcmp(name, "chaos") == 0) {
121 1.1 tsubai int child;
122 1.1 tsubai
123 1.1 tsubai if (OF_getprop(node, "reg", reg, sizeof(reg)) != 8)
124 1.1 tsubai continue;
125 1.1 tsubai
126 1.2 tsubai pci_bridges[n].iot = (bus_space_tag_t)reg[0];
127 1.2 tsubai pci_bridges[n].addr = mapiodev(reg[0] + 0x800000, 4);
128 1.2 tsubai pci_bridges[n].data = mapiodev(reg[0] + 0xc00000, 4);
129 1.2 tsubai pci_bridges[n].pc = n;
130 1.5 tsubai
131 1.5 tsubai if (OF_getprop(node, "bus-range",
132 1.5 tsubai reg, sizeof(reg)) != 8) {
133 1.5 tsubai pci_bridges[n].addr = NULL;
134 1.5 tsubai continue;
135 1.5 tsubai }
136 1.5 tsubai pci_bridges[n].bus = reg[0];
137 1.5 tsubai
138 1.3 tsubai bandit_init(n);
139 1.1 tsubai
140 1.1 tsubai child = OF_child(node);
141 1.1 tsubai while (child) {
142 1.3 tsubai config_slot(child, n);
143 1.1 tsubai child = OF_peer(child);
144 1.1 tsubai }
145 1.3 tsubai n++;
146 1.1 tsubai }
147 1.2 tsubai if (strcmp(name, "pci") == 0) { /* XXX This is not a bandit :) */
148 1.2 tsubai int child;
149 1.2 tsubai
150 1.2 tsubai if (OF_getprop(node, "reg", reg, sizeof(reg)) != 8)
151 1.2 tsubai continue;
152 1.2 tsubai
153 1.2 tsubai pci_bridges[n].iot = (bus_space_tag_t)reg[0];
154 1.2 tsubai pci_bridges[n].addr = mapiodev(0xfec00000, 4); /* XXX */
155 1.2 tsubai pci_bridges[n].data = mapiodev(0xfee00000, 4); /* XXX */
156 1.2 tsubai pci_bridges[n].pc = PCI_CHIPSET_MPC106; /* for now */
157 1.4 tsubai
158 1.5 tsubai if (OF_getprop(node, "bus-range",
159 1.5 tsubai reg, sizeof(reg)) != 8) {
160 1.5 tsubai pci_bridges[n].addr = NULL;
161 1.5 tsubai continue;
162 1.5 tsubai }
163 1.5 tsubai pci_bridges[n].bus = reg[0];
164 1.5 tsubai
165 1.4 tsubai child = OF_child(node);
166 1.4 tsubai while (child) {
167 1.4 tsubai config_slot(child, pci_bridges[n].pc);
168 1.4 tsubai child = OF_peer(child);
169 1.4 tsubai }
170 1.5 tsubai n++;
171 1.2 tsubai }
172 1.2 tsubai
173 1.1 tsubai node = OF_peer(node);
174 1.1 tsubai }
175 1.1 tsubai }
176 1.1 tsubai
177 1.1 tsubai void
178 1.3 tsubai config_slot(node, pc)
179 1.1 tsubai int node;
180 1.3 tsubai pci_chipset_tag_t pc;
181 1.1 tsubai {
182 1.1 tsubai pcitag_t tag;
183 1.3 tsubai int sp, irq, intr, csr;
184 1.3 tsubai int bus, dev, func;
185 1.3 tsubai int sz;
186 1.3 tsubai u_int reg[40], *rp;
187 1.1 tsubai
188 1.3 tsubai sz = OF_getprop(node, "assigned-addresses", reg, sizeof(reg));
189 1.3 tsubai if (sz < 4)
190 1.1 tsubai return;
191 1.1 tsubai
192 1.1 tsubai /*
193 1.3 tsubai * npt000ss bbbbbbbb dddddfff rrrrrrrr
194 1.1 tsubai *
195 1.3 tsubai * ss space code (01:I/O, 10:32bit mem)
196 1.3 tsubai * b... 8-bit Bus Number
197 1.3 tsubai * d... 5-bit Device Number
198 1.3 tsubai * f... 3-bit Function Number
199 1.3 tsubai * r... 8-bit Register Number
200 1.1 tsubai */
201 1.3 tsubai rp = ®[0];
202 1.3 tsubai bus = (*rp >> 16) & 0xff;
203 1.3 tsubai dev = (*rp >> 11) & 0x1f;
204 1.3 tsubai func = (*rp >> 8) & 0x07;
205 1.3 tsubai
206 1.3 tsubai tag = pci_make_tag(pc, bus, dev, func);
207 1.3 tsubai csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
208 1.3 tsubai
209 1.3 tsubai /* Fix mem/io bits */
210 1.3 tsubai while (sz > 0) {
211 1.3 tsubai sp = (*rp >> 24) & 0x03;
212 1.3 tsubai if (sp == 1)
213 1.3 tsubai csr |= PCI_COMMAND_IO_ENABLE;
214 1.3 tsubai if (sp == 2)
215 1.3 tsubai csr |= PCI_COMMAND_MEM_ENABLE;
216 1.3 tsubai sz -= 5 * sizeof(int);
217 1.3 tsubai rp += 5;
218 1.3 tsubai }
219 1.3 tsubai
220 1.3 tsubai pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr);
221 1.1 tsubai
222 1.3 tsubai /* Fix intr bits */
223 1.1 tsubai if (OF_getprop(node, "AAPL,interrupts", &irq, sizeof(irq)) ==
224 1.1 tsubai sizeof(irq)) {
225 1.1 tsubai
226 1.1 tsubai intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
227 1.1 tsubai intr = (intr & 0xffffff00) | (irq & 0xff);
228 1.1 tsubai pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr);
229 1.3 tsubai }
230 1.1 tsubai
231 1.1 tsubai }
232 1.3 tsubai
233 1.3 tsubai /*
234 1.3 tsubai * slot A1 pci0 dev 13 irq 23
235 1.3 tsubai * B1 pci0 dev 14 irq 24
236 1.3 tsubai * C1 pci0 dev 15 irq 25
237 1.3 tsubai * D2 pci1 dev 13 irq 27
238 1.3 tsubai * E2 pci1 dev 14 irq 28
239 1.3 tsubai * F2 pci1 dev 15 irq 29
240 1.3 tsubai */
241