gtpci.c revision 1.1 1 1.1 matt /* $NetBSD: gtpci.c,v 1.1 2003/03/05 22:08:22 matt Exp $ */
2 1.1 matt
3 1.1 matt /*
4 1.1 matt * Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
5 1.1 matt * All rights reserved.
6 1.1 matt *
7 1.1 matt * Redistribution and use in source and binary forms, with or without
8 1.1 matt * modification, are permitted provided that the following conditions
9 1.1 matt * are met:
10 1.1 matt * 1. Redistributions of source code must retain the above copyright
11 1.1 matt * notice, this list of conditions and the following disclaimer.
12 1.1 matt * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 matt * notice, this list of conditions and the following disclaimer in the
14 1.1 matt * documentation and/or other materials provided with the distribution.
15 1.1 matt * 3. All advertising materials mentioning features or use of this software
16 1.1 matt * must display the following acknowledgement:
17 1.1 matt * This product includes software developed for the NetBSD Project by
18 1.1 matt * Allegro Networks, Inc., and Wasabi Systems, Inc.
19 1.1 matt * 4. The name of Allegro Networks, Inc. may not be used to endorse
20 1.1 matt * or promote products derived from this software without specific prior
21 1.1 matt * written permission.
22 1.1 matt * 5. The name of Wasabi Systems, Inc. may not be used to endorse
23 1.1 matt * or promote products derived from this software without specific prior
24 1.1 matt * written permission.
25 1.1 matt *
26 1.1 matt * THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
27 1.1 matt * WASABI SYSTEMS, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
28 1.1 matt * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
29 1.1 matt * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30 1.1 matt * IN NO EVENT SHALL EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
31 1.1 matt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 1.1 matt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 1.1 matt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 1.1 matt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 1.1 matt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 1.1 matt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 1.1 matt * POSSIBILITY OF SUCH DAMAGE.
38 1.1 matt */
39 1.1 matt
40 1.1 matt #include "opt_marvell.h"
41 1.1 matt #include <sys/param.h>
42 1.1 matt #include <sys/device.h>
43 1.1 matt #include <sys/extent.h>
44 1.1 matt #include <sys/malloc.h>
45 1.1 matt #include <lib/libkern/libkern.h>
46 1.1 matt
47 1.1 matt #define _BUS_SPACE_PRIVATE
48 1.1 matt #define _BUS_DMA_PRIVATE
49 1.1 matt #include <machine/bus.h>
50 1.1 matt #include <machine/intr.h>
51 1.1 matt
52 1.1 matt #include <dev/pci/pcireg.h>
53 1.1 matt #include <dev/pci/pcivar.h>
54 1.1 matt #include <dev/pci/pciconf.h>
55 1.1 matt #include <dev/marvell/gtreg.h>
56 1.1 matt #include <dev/marvell/gtvar.h>
57 1.1 matt #include <dev/marvell/gtintrreg.h>
58 1.1 matt #include <dev/marvell/gtpcireg.h>
59 1.1 matt #include <dev/marvell/gtpcivar.h>
60 1.1 matt #include <dev/marvell/gtvar.h>
61 1.1 matt
62 1.1 matt static int gtpci_error_intr(void *);
63 1.1 matt
64 1.1 matt static void gtpci_bus_attach_hook(struct device *, struct device *,
65 1.1 matt struct pcibus_attach_args *);
66 1.1 matt static int gtpci_bus_maxdevs(pci_chipset_tag_t, int);
67 1.1 matt
68 1.1 matt static const char *
69 1.1 matt gtpci_intr_string(pci_chipset_tag_t, pci_intr_handle_t);
70 1.1 matt static const struct evcnt *
71 1.1 matt gtpci_intr_evcnt(pci_chipset_tag_t, pci_intr_handle_t);
72 1.1 matt static void *gtpci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t,
73 1.1 matt int, int (*)(void *), void *);
74 1.1 matt static void gtpci_intr_disestablish(pci_chipset_tag_t, void *);
75 1.1 matt
76 1.1 matt #ifdef DEBUG
77 1.1 matt int gtpci_debug = 0;
78 1.1 matt #endif
79 1.1 matt
80 1.1 matt struct gtpci_softc {
81 1.1 matt struct device gtpci_dev;
82 1.1 matt struct pci_chipset gtpci_pc;
83 1.1 matt };
84 1.1 matt
85 1.1 matt static int gtpci_cfprint(void *, const char *);
86 1.1 matt static int gtpci_match(struct device *, struct cfdata *, void *);
87 1.1 matt static void gtpci_attach(struct device *, struct device *, void *);
88 1.1 matt
89 1.1 matt CFATTACH_DECL(gtpci, sizeof(struct gtpci_softc),
90 1.1 matt gtpci_match, gtpci_attach, NULL, NULL);
91 1.1 matt
92 1.1 matt extern struct cfdriver gtpci_cd;
93 1.1 matt
94 1.1 matt static int gtpci_nbusses;
95 1.1 matt
96 1.1 matt const struct pci_chipset_functions gtpci_functions = {
97 1.1 matt gtpci_bus_attach_hook,
98 1.1 matt gtpci_bus_maxdevs,
99 1.1 matt gtpci_md_bus_devorder,
100 1.1 matt
101 1.1 matt gtpci_make_tag,
102 1.1 matt gtpci_decompose_tag,
103 1.1 matt
104 1.1 matt gtpci_conf_read,
105 1.1 matt gtpci_conf_write,
106 1.1 matt gtpci_md_conf_hook,
107 1.1 matt gtpci_md_conf_interrupt,
108 1.1 matt
109 1.1 matt gtpci_md_intr_map,
110 1.1 matt gtpci_intr_string,
111 1.1 matt gtpci_intr_evcnt,
112 1.1 matt gtpci_intr_establish,
113 1.1 matt gtpci_intr_disestablish
114 1.1 matt };
115 1.1 matt
116 1.1 matt int
117 1.1 matt gtpci_match(struct device *parent, struct cfdata *self, void *aux)
118 1.1 matt {
119 1.1 matt struct gt_attach_args *ga = aux;
120 1.1 matt
121 1.1 matt if (gtpci_nbusses >= GTPCI_NBUS) {
122 1.1 matt return 0;
123 1.1 matt }
124 1.1 matt
125 1.1 matt if (strcmp(ga->ga_name, gtpci_cd.cd_name) != 0) {
126 1.1 matt return 0;
127 1.1 matt }
128 1.1 matt
129 1.1 matt return 1;
130 1.1 matt }
131 1.1 matt
132 1.1 matt int
133 1.1 matt gtpci_cfprint(void *aux, const char *pnp)
134 1.1 matt {
135 1.1 matt struct pcibus_attach_args *pba = (struct pcibus_attach_args *) aux;
136 1.1 matt
137 1.1 matt if (pnp)
138 1.1 matt printf("pci at %s", pnp);
139 1.1 matt
140 1.1 matt printf(" bus %d", pba->pba_bus);
141 1.1 matt
142 1.1 matt return (UNCONF);
143 1.1 matt }
144 1.1 matt
145 1.1 matt void
146 1.1 matt gtpci_attach(struct device *parent, struct device *self, void *aux)
147 1.1 matt {
148 1.1 matt struct pcibus_attach_args pba;
149 1.1 matt struct gt_attach_args *ga = aux;
150 1.1 matt struct gtpci_softc *gtp = (struct gtpci_softc *) self;
151 1.1 matt struct gt_softc *gt = (struct gt_softc *) parent;
152 1.1 matt struct pci_chipset *pc;
153 1.1 matt uint32_t data;
154 1.1 matt int busno;
155 1.1 matt
156 1.1 matt printf("\n");
157 1.1 matt
158 1.1 matt busno = ga->ga_unit;
159 1.1 matt
160 1.1 matt pc = >p->gtpci_pc;
161 1.1 matt
162 1.1 matt gt->gt_pcis[busno] = pc;
163 1.1 matt memset(pc, 0, sizeof(*pc));
164 1.1 matt
165 1.1 matt pc->pc_funcs = >pci_functions;
166 1.1 matt pc->pc_parent = self;
167 1.1 matt pc->pc_md.mdpc_busno = busno;
168 1.1 matt
169 1.1 matt pc->pc_md.mdpc_cfgaddr = PCI_CONFIG_ADDR(busno);
170 1.1 matt pc->pc_md.mdpc_cfgdata = PCI_CONFIG_DATA(busno);
171 1.1 matt pc->pc_md.mdpc_syncreg = PCI_SYNC_REG(busno);
172 1.1 matt pc->pc_md.mdpc_gt = gt;
173 1.1 matt
174 1.1 matt switch (busno) {
175 1.1 matt case 0:
176 1.1 matt pc->pc_md.mdpc_io_bs = gt->gt_pci0_iot;
177 1.1 matt pc->pc_md.mdpc_mem_bs = gt->gt_pci0_memt;
178 1.1 matt break;
179 1.1 matt case 1:
180 1.1 matt pc->pc_md.mdpc_io_bs = gt->gt_pci1_iot;
181 1.1 matt pc->pc_md.mdpc_mem_bs = gt->gt_pci1_memt;
182 1.1 matt break;
183 1.1 matt default:
184 1.1 matt break;
185 1.1 matt }
186 1.1 matt
187 1.1 matt pba.pba_pc = pc;
188 1.1 matt pba.pba_bus = 0;
189 1.1 matt pba.pba_busname = "pci";
190 1.1 matt pba.pba_iot = pc->pc_md.mdpc_io_bs;
191 1.1 matt pba.pba_memt = pc->pc_md.mdpc_mem_bs;
192 1.1 matt pba.pba_dmat = gt->gt_dmat;
193 1.1 matt pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;
194 1.1 matt
195 1.1 matt data = gtpci_read(pc, PCI_COMMAND(pc->pc_md.mdpc_busno));
196 1.1 matt if (data & PCI_CMD_MRdMul)
197 1.1 matt pba.pba_flags |= PCI_FLAGS_MRM_OKAY;
198 1.1 matt if (data & PCI_CMD_MRdLine)
199 1.1 matt pba.pba_flags |= PCI_FLAGS_MRL_OKAY;
200 1.1 matt pba.pba_flags |= PCI_FLAGS_MWI_OKAY;
201 1.1 matt
202 1.1 matt gt_watchdog_service();
203 1.1 matt
204 1.1 matt config_found(self, &pba, gtpci_cfprint);
205 1.1 matt
206 1.1 matt gt_watchdog_service();
207 1.1 matt
208 1.1 matt /*
209 1.1 matt * clear any pre-existing error interrupt(s)
210 1.1 matt * clear latched pci error registers
211 1.1 matt * establish ISRs for PCI errors
212 1.1 matt * enable PCI error interrupts
213 1.1 matt */
214 1.1 matt gtpci_write(pc, PCI_ERROR_CAUSE(pc->pc_md.mdpc_busno), 0);
215 1.1 matt (void)gtpci_read(pc, PCI_ERROR_DATA_LOW(pc->pc_md.mdpc_busno));
216 1.1 matt (void)gtpci_read(pc, PCI_ERROR_DATA_HIGH(pc->pc_md.mdpc_busno));
217 1.1 matt (void)gtpci_read(pc, PCI_ERROR_COMMAND(pc->pc_md.mdpc_busno));
218 1.1 matt (void)gtpci_read(pc, PCI_ERROR_ADDRESS_HIGH(pc->pc_md.mdpc_busno));
219 1.1 matt (void)gtpci_read(pc, PCI_ERROR_ADDRESS_LOW(pc->pc_md.mdpc_busno));
220 1.1 matt if (pc->pc_md.mdpc_busno == 0) {
221 1.1 matt intr_establish(IRQ_PCI0_0, IST_LEVEL, IPL_GTERR,
222 1.1 matt gtpci_error_intr, pc);
223 1.1 matt intr_establish(IRQ_PCI0_1, IST_LEVEL, IPL_GTERR,
224 1.1 matt gtpci_error_intr, pc);
225 1.1 matt intr_establish(IRQ_PCI0_2, IST_LEVEL, IPL_GTERR,
226 1.1 matt gtpci_error_intr, pc);
227 1.1 matt printf("%s: %s%d error interrupts at irqs %d, %d, %d\n",
228 1.1 matt pc->pc_parent->dv_xname, "pci", busno,
229 1.1 matt IRQ_PCI0_0, IRQ_PCI0_1, IRQ_PCI0_2);
230 1.1 matt
231 1.1 matt } else {
232 1.1 matt intr_establish(IRQ_PCI1_0, IST_LEVEL, IPL_GTERR,
233 1.1 matt gtpci_error_intr, pc);
234 1.1 matt intr_establish(IRQ_PCI1_1, IST_LEVEL, IPL_GTERR,
235 1.1 matt gtpci_error_intr, pc);
236 1.1 matt intr_establish(IRQ_PCI1_2, IST_LEVEL, IPL_GTERR,
237 1.1 matt gtpci_error_intr, pc);
238 1.1 matt printf("%s: %s%d error interrupts at irqs %d, %d, %d\n",
239 1.1 matt pc->pc_parent->dv_xname, "pci", busno,
240 1.1 matt IRQ_PCI1_0, IRQ_PCI1_1, IRQ_PCI1_2);
241 1.1 matt }
242 1.1 matt gtpci_write(pc, PCI_ERROR_MASK(pc->pc_md.mdpc_busno), PCI_SERRMSK_ALL_ERRS);
243 1.1 matt
244 1.1 matt gtpci_nbusses++;
245 1.1 matt }
246 1.1 matt
247 1.1 matt void
248 1.1 matt gtpci_bus_attach_hook(struct device *parent, struct device *self,
249 1.1 matt struct pcibus_attach_args *pba)
250 1.1 matt {
251 1.1 matt struct gt_softc *gt;
252 1.1 matt pci_chipset_tag_t pc = pba->pba_pc;
253 1.1 matt pcitag_t tag;
254 1.1 matt uint32_t data;
255 1.1 matt int i;
256 1.1 matt
257 1.1 matt if (pc->pc_parent != parent)
258 1.1 matt return;
259 1.1 matt
260 1.1 matt data = gtpci_read(pc, PCI_MODE(pc->pc_md.mdpc_busno));
261 1.1 matt printf(": id %d%s%s%s%s%s%s%s%s",
262 1.1 matt PCI_MODE_PciID_GET(data),
263 1.1 matt (data & PCI_MODE_Pci64) ? ", 64bit" : "",
264 1.1 matt (data & PCI_MODE_ExpRom) ? ", Expansion Rom" : "",
265 1.1 matt (data & PCI_MODE_VPD) ? ", VPD" : "",
266 1.1 matt (data & PCI_MODE_MSI) ? ", MSI" : "",
267 1.1 matt (data & PCI_MODE_PMG) ? ", PMG" : "",
268 1.1 matt (data & PCI_MODE_HotSwap) ? ", HotSwap" : "",
269 1.1 matt (data & PCI_MODE_BIST) ? ", BIST" : "",
270 1.1 matt (data & PCI_MODE_PRst) ? "" : ", PRst");
271 1.1 matt
272 1.1 matt while ((data & PCI_MODE_PRst) == 0) {
273 1.1 matt data = gtpci_read(pc, PCI_MODE(pc->pc_md.mdpc_busno));
274 1.1 matt i = (i + 1) & 0x7ffffff; printf(".");
275 1.1 matt }
276 1.1 matt
277 1.1 matt gt = (struct gt_softc *) pc->pc_md.mdpc_gt;
278 1.1 matt gtpci_config_bus(pc, pc->pc_md.mdpc_busno);
279 1.1 matt
280 1.1 matt tag = gtpci_make_tag(pc, 0, 0, 0);
281 1.1 matt data = gtpci_read(pc, PCI_BASE_ADDR_REGISTERS_ENABLE(pc->pc_md.mdpc_busno));
282 1.1 matt printf("\n%s: BARs enabled: %#x", self->dv_xname, data);
283 1.1 matt
284 1.1 matt #if DEBUG
285 1.1 matt printf("\n%s: 0:0:0\n", self->dv_xname);
286 1.1 matt printf(" %sSCS0=%#010x",
287 1.1 matt (data & 1) ? "-" : "+",
288 1.1 matt gtpci_conf_read(pc, tag, 0x10));
289 1.1 matt printf("/%#010x", gtpci_read(pc,
290 1.1 matt PCI_SCS0_BAR_SIZE(pc->pc_md.mdpc_busno))+0x1000);
291 1.1 matt printf(" remap %#010x\n",
292 1.1 matt gtpci_read(pc, PCI_SCS0_BASE_ADDR_REMAP(pc->pc_md.mdpc_busno)));
293 1.1 matt
294 1.1 matt printf(" %sSCS1=%#010x",
295 1.1 matt (data & 2) ? "-" : "+",
296 1.1 matt gtpci_conf_read(pc, tag, 0x14));
297 1.1 matt printf("/%#010x",
298 1.1 matt gtpci_read(pc, PCI_SCS1_BAR_SIZE(pc->pc_md.mdpc_busno))+0x1000);
299 1.1 matt printf(" remap %#010x\n",
300 1.1 matt gtpci_read(pc, PCI_SCS1_BASE_ADDR_REMAP(pc->pc_md.mdpc_busno)));
301 1.1 matt
302 1.1 matt printf(" %sSCS2=%#010x",
303 1.1 matt (data & 4) ? "-" : "+",
304 1.1 matt gtpci_conf_read(pc, tag, 0x18));
305 1.1 matt printf("/%#010x",
306 1.1 matt gtpci_read(pc, PCI_SCS2_BAR_SIZE(pc->pc_md.mdpc_busno))+0x1000);
307 1.1 matt printf(" remap %#010x\n",
308 1.1 matt gtpci_read(pc, PCI_SCS2_BASE_ADDR_REMAP(pc->pc_md.mdpc_busno)));
309 1.1 matt
310 1.1 matt printf(" %sSCS3=%#010x",
311 1.1 matt (data & 8) ? "-" : "+",
312 1.1 matt gtpci_conf_read(pc, tag, 0x1c));
313 1.1 matt printf("/%#010x",
314 1.1 matt gtpci_read(pc, PCI_SCS3_BAR_SIZE(pc->pc_md.mdpc_busno))+0x1000);
315 1.1 matt printf(" remap %#010x\n",
316 1.1 matt gtpci_read(pc, PCI_SCS3_BASE_ADDR_REMAP(pc->pc_md.mdpc_busno)));
317 1.1 matt
318 1.1 matt printf(" %sIMem=%#010x",
319 1.1 matt (data & PCI_BARE_IntMemEn) ? "-" : "+",
320 1.1 matt gtpci_conf_read(pc, tag, 0x20));
321 1.1 matt printf("\n");
322 1.1 matt printf(" %sIIO=%#010x",
323 1.1 matt (data & PCI_BARE_IntIOEn) ? "-" : "+",
324 1.1 matt gtpci_conf_read(pc, tag, 0x24));
325 1.1 matt printf("\n");
326 1.1 matt tag = gtpci_make_tag(pc, 0, 0, 1);
327 1.1 matt printf(" %sCS0=%#010x",
328 1.1 matt (data & PCI_BARE_CS0En) ? "-" : "+",
329 1.1 matt gtpci_conf_read(pc, tag, 0x10));
330 1.1 matt printf("/%#010x",
331 1.1 matt gtpci_read(pc, PCI_CS0_BAR_SIZE(pc->pc_md.mdpc_busno))+0x1000);
332 1.1 matt printf(" remap %#010x\n",
333 1.1 matt gtpci_read(pc, PCI_CS0_BASE_ADDR_REMAP(pc->pc_md.mdpc_busno)));
334 1.1 matt
335 1.1 matt printf(" %sCS1=%#010x",
336 1.1 matt (data & PCI_BARE_CS1En) ? "-" : "+",
337 1.1 matt gtpci_conf_read(pc, tag, 0x14));
338 1.1 matt printf("/%#010x",
339 1.1 matt gtpci_read(pc, PCI_CS1_BAR_SIZE(pc->pc_md.mdpc_busno))+0x1000);
340 1.1 matt printf(" remap %#010x\n",
341 1.1 matt gtpci_read(pc, PCI_CS1_BASE_ADDR_REMAP(pc->pc_md.mdpc_busno)));
342 1.1 matt
343 1.1 matt printf(" %sCS2=%#010x",
344 1.1 matt (data & PCI_BARE_CS2En) ? "-" : "+",
345 1.1 matt gtpci_conf_read(pc, tag, 0x18));
346 1.1 matt printf("/%#010x",
347 1.1 matt gtpci_read(pc, PCI_CS2_BAR_SIZE(pc->pc_md.mdpc_busno))+0x1000);
348 1.1 matt printf(" remap %#010x\n",
349 1.1 matt gtpci_read(pc, PCI_CS2_BASE_ADDR_REMAP(pc->pc_md.mdpc_busno)));
350 1.1 matt
351 1.1 matt printf(" %sCS3=%#010x",
352 1.1 matt (data & PCI_BARE_CS3En) ? "-" : "+",
353 1.1 matt gtpci_conf_read(pc, tag, 0x1c));
354 1.1 matt printf("/%#010x",
355 1.1 matt gtpci_read(pc, PCI_CS3_BAR_SIZE(pc->pc_md.mdpc_busno))+0x1000);
356 1.1 matt printf(" remap %#010x\n",
357 1.1 matt gtpci_read(pc, PCI_CS3_BASE_ADDR_REMAP(pc->pc_md.mdpc_busno)));
358 1.1 matt
359 1.1 matt printf(" %sBootCS=%#010x",
360 1.1 matt (data & PCI_BARE_BootCSEn) ? "-" : "+",
361 1.1 matt gtpci_conf_read(pc, tag, 0x20));
362 1.1 matt printf("/%#010x",
363 1.1 matt gtpci_read(pc, PCI_BOOTCS_BAR_SIZE(pc->pc_md.mdpc_busno))+0x1000);
364 1.1 matt printf(" remap %#010x\n",
365 1.1 matt gtpci_read(pc, PCI_BOOTCS_ADDR_REMAP(pc->pc_md.mdpc_busno)));
366 1.1 matt
367 1.1 matt tag = gtpci_make_tag(pc, 0, 0, 2);
368 1.1 matt printf(" %sP2PM0=%#010x",
369 1.1 matt (data & PCI_BARE_P2PMem0En) ? "-" : "+",
370 1.1 matt gtpci_conf_read(pc, tag, 0x10));
371 1.1 matt printf("/%#010x",
372 1.1 matt gtpci_read(pc, PCI_P2P_MEM0_BAR_SIZE(pc->pc_md.mdpc_busno))+0x1000);
373 1.1 matt printf(" remap %#010x.%#010x\n",
374 1.1 matt gtpci_read(pc, PCI_P2P_MEM0_BASE_ADDR_REMAP_HIGH(pc->pc_md.mdpc_busno)),
375 1.1 matt gtpci_read(pc, PCI_P2P_MEM0_BASE_ADDR_REMAP_LOW(pc->pc_md.mdpc_busno)));
376 1.1 matt
377 1.1 matt printf(" %sP2PM1=%#010x",
378 1.1 matt (data & PCI_BARE_P2PMem1En) ? "-" : "+",
379 1.1 matt gtpci_conf_read(pc, tag, 0x14));
380 1.1 matt printf("/%#010x",
381 1.1 matt gtpci_read(pc, PCI_P2P_MEM1_BAR_SIZE(pc->pc_md.mdpc_busno))+0x1000);
382 1.1 matt printf(" remap %#010x.%#010x\n",
383 1.1 matt gtpci_read(pc, PCI_P2P_MEM1_BASE_ADDR_REMAP_HIGH(pc->pc_md.mdpc_busno)),
384 1.1 matt gtpci_read(pc, PCI_P2P_MEM1_BASE_ADDR_REMAP_LOW(pc->pc_md.mdpc_busno)));
385 1.1 matt
386 1.1 matt printf(" %sP2PIO=%#010x",
387 1.1 matt (data & PCI_BARE_P2PIOEn) ? "-" : "+",
388 1.1 matt gtpci_conf_read(pc, tag, 0x18));
389 1.1 matt printf("/%#010x",
390 1.1 matt gtpci_read(pc, PCI_P2P_IO_BAR_SIZE(pc->pc_md.mdpc_busno))+0x1000);
391 1.1 matt printf(" remap %#010x\n",
392 1.1 matt gtpci_read(pc, PCI_P2P_IO_BASE_ADDR_REMAP(pc->pc_md.mdpc_busno)));
393 1.1 matt
394 1.1 matt printf(" %sCPU=%#010x",
395 1.1 matt (data & PCI_BARE_CPUEn) ? "-" : "+",
396 1.1 matt gtpci_conf_read(pc, tag, 0x1c));
397 1.1 matt printf("/%#010x",
398 1.1 matt gtpci_read(pc, PCI_CPU_BAR_SIZE(pc->pc_md.mdpc_busno))+0x1000);
399 1.1 matt printf(" remap %#010x\n",
400 1.1 matt gtpci_read(pc, PCI_CPU_BASE_ADDR_REMAP(pc->pc_md.mdpc_busno)));
401 1.1 matt #endif
402 1.1 matt tag = gtpci_make_tag(pc, 0, 0, 0);
403 1.1 matt data = gtpci_read(pc, PCI_COMMAND(pc->pc_md.mdpc_busno));
404 1.1 matt if (data & (PCI_CMD_MSwapEn|PCI_CMD_SSwapEn)) {
405 1.1 matt
406 1.1 matt printf("\n%s: ", self->dv_xname);
407 1.1 matt
408 1.1 matt if (data & PCI_CMD_MSwapEn) {
409 1.1 matt switch (data & (PCI_CMD_MWordSwap|PCI_CMD_MByteSwap)) {
410 1.1 matt case PCI_CMD_MWordSwap:
411 1.1 matt printf(" mswap=w"); break;
412 1.1 matt case PCI_CMD_MByteSwap:
413 1.1 matt printf(" mswap=b"); break;
414 1.1 matt case PCI_CMD_MWordSwap|PCI_CMD_MByteSwap:
415 1.1 matt printf(" mswap=b+w"); break;
416 1.1 matt case 0:
417 1.1 matt printf(" mswap=none"); break;
418 1.1 matt }
419 1.1 matt }
420 1.1 matt
421 1.1 matt if (data & PCI_CMD_SSwapEn) {
422 1.1 matt switch (data & (PCI_CMD_SWordSwap|PCI_CMD_SByteSwap)) {
423 1.1 matt case PCI_CMD_SWordSwap:
424 1.1 matt printf(" sswap=w"); break;
425 1.1 matt case PCI_CMD_SByteSwap:
426 1.1 matt printf(" sswap=b"); break;
427 1.1 matt case PCI_CMD_SWordSwap|PCI_CMD_SByteSwap:
428 1.1 matt printf(" sswap=b+w"); break;
429 1.1 matt case 0:
430 1.1 matt printf(" sswap=none"); break;
431 1.1 matt }
432 1.1 matt }
433 1.1 matt }
434 1.1 matt
435 1.1 matt #if DEBUG
436 1.1 matt for (i = 0; i < 8; i++) {
437 1.1 matt printf("\n%s: Access Control %d: ", self->dv_xname, i);
438 1.1 matt printf("base(hi=%#x,lo=%#x)=0x%08x.%03xxxxxx",
439 1.1 matt PCI_ACCESS_CONTROL_BASE_HIGH(pc->pc_md.mdpc_busno, i),
440 1.1 matt PCI_ACCESS_CONTROL_BASE_LOW(pc->pc_md.mdpc_busno, i),
441 1.1 matt gtpci_read(pc,
442 1.1 matt PCI_ACCESS_CONTROL_BASE_HIGH(pc->pc_md.mdpc_busno, i)),
443 1.1 matt gtpci_read(pc,
444 1.1 matt PCI_ACCESS_CONTROL_BASE_LOW(pc->pc_md.mdpc_busno, i)) & 0xfff);
445 1.1 matt printf(" cfg=%#x",
446 1.1 matt gtpci_read(pc,
447 1.1 matt PCI_ACCESS_CONTROL_BASE_LOW(pc->pc_md.mdpc_busno, i)) & ~0xfff);
448 1.1 matt printf(" top(%#x)=%#x",
449 1.1 matt PCI_ACCESS_CONTROL_TOP(pc->pc_md.mdpc_busno, i),
450 1.1 matt gtpci_read(pc,
451 1.1 matt PCI_ACCESS_CONTROL_TOP(pc->pc_md.mdpc_busno, i)));
452 1.1 matt }
453 1.1 matt #endif
454 1.1 matt
455 1.1 matt #if 0
456 1.1 matt gtpci_write(pc, PCI_ACCESS_CONTROL_BASE_HIGH(pc->pc_md.mdpc_busno, 0), 0);
457 1.1 matt gtpci_write(pc, PCI_ACCESS_CONTROL_BASE_LOW(pc->pc_md.mdpc_busno, 0),
458 1.1 matt 0x01001000);
459 1.1 matt gtpci_write(pc, PCI_ACCESS_CONTROL_TOP(pc->pc_md.mdpc_busno, 0),
460 1.1 matt 0x00000020);
461 1.1 matt #endif
462 1.1 matt }
463 1.1 matt
464 1.1 matt static const char * const gtpci_error_strings[] = PCI_IC_SEL_Strings;
465 1.1 matt
466 1.1 matt int
467 1.1 matt gtpci_error_intr(void *arg)
468 1.1 matt {
469 1.1 matt pci_chipset_tag_t pc = arg;
470 1.1 matt uint32_t cause, mask, errmask;
471 1.1 matt u_int32_t alo, ahi, dlo, dhi, cmd;
472 1.1 matt int i;
473 1.1 matt
474 1.1 matt cause = gtpci_read(pc, PCI_ERROR_CAUSE(pc->pc_md.mdpc_busno));
475 1.1 matt errmask = gtpci_read(pc, PCI_ERROR_MASK(pc->pc_md.mdpc_busno));
476 1.1 matt cause &= (errmask | (0x1f << 27));
477 1.1 matt gtpci_write(pc, PCI_ERROR_CAUSE(pc->pc_md.mdpc_busno), ~cause);
478 1.1 matt printf("%s: pci%d error: cause=%#x mask=%#x",
479 1.1 matt pc->pc_parent->dv_xname, pc->pc_md.mdpc_busno, cause, errmask);
480 1.1 matt if ((cause & ~(0x1f << 27)) == 0) {
481 1.1 matt printf(" ?\n");
482 1.1 matt return 0;
483 1.1 matt }
484 1.1 matt
485 1.1 matt for (i = 0, mask = 1; i <= 26; i++, mask += mask)
486 1.1 matt if (mask & cause)
487 1.1 matt printf(" %s", gtpci_error_strings[i]);
488 1.1 matt
489 1.1 matt /*
490 1.1 matt * "no new data is latched until the PCI Error Low Address
491 1.1 matt * register is read. This means that PCI Error Low Address
492 1.1 matt * register must be the last register read by the interrupt
493 1.1 matt * handler."
494 1.1 matt */
495 1.1 matt dlo = gtpci_read(pc, PCI_ERROR_DATA_LOW(pc->pc_md.mdpc_busno));
496 1.1 matt dhi = gtpci_read(pc, PCI_ERROR_DATA_HIGH(pc->pc_md.mdpc_busno));
497 1.1 matt cmd = gtpci_read(pc, PCI_ERROR_COMMAND(pc->pc_md.mdpc_busno));
498 1.1 matt ahi = gtpci_read(pc, PCI_ERROR_ADDRESS_HIGH(pc->pc_md.mdpc_busno));
499 1.1 matt alo = gtpci_read(pc, PCI_ERROR_ADDRESS_LOW(pc->pc_md.mdpc_busno));
500 1.1 matt printf("\n%s: pci%d error: %s cmd %#x data %#x.%#x address=%#x.%#x\n",
501 1.1 matt pc->pc_parent->dv_xname, pc->pc_md.mdpc_busno,
502 1.1 matt gtpci_error_strings[PCI_IC_SEL_GET(cause)],
503 1.1 matt cmd, dhi, dlo, ahi, alo);
504 1.1 matt
505 1.1 matt #if defined(DEBUG) && defined(DDB)
506 1.1 matt if (gtpci_debug > 0)
507 1.1 matt Debugger();
508 1.1 matt #endif
509 1.1 matt return 1;
510 1.1 matt }
511 1.1 matt
512 1.1 matt
513 1.1 matt #if 0
514 1.1 matt void
515 1.1 matt gtpci_bs_region_add(pci_chipset_tag_t pc, struct discovery_bus_space *bs,
516 1.1 matt struct gt_softc *gt, bus_addr_t lo, bus_addr_t hi)
517 1.1 matt {
518 1.1 matt /* See how I/O space is configured. Read the base and top
519 1.1 matt * registers.
520 1.1 matt */
521 1.1 matt paddr_t pbasel, pbaseh;
522 1.1 matt uint32_t datal, datah;
523 1.1 matt
524 1.1 matt datal = gtpci_read(pc, lo);
525 1.1 matt datah = gtpci_read(pc, hi);
526 1.1 matt pbasel = GT_LowAddr_GET(datal);
527 1.1 matt pbaseh = GT_HighAddr_GET(datah);
528 1.1 matt /*
529 1.1 matt * If the start is greater than the end, ignore the region.
530 1.1 matt */
531 1.1 matt if (pbaseh < pbasel)
532 1.1 matt return;
533 1.1 matt if ((pbasel & gt->gt_iobat_mask) == gt->gt_iobat_pbase
534 1.1 matt && (pbaseh & gt->gt_iobat_mask) == gt->gt_iobat_pbase) {
535 1.1 matt bs->bs_regions[bs->bs_nregion].br_vbase =
536 1.1 matt gt->gt_iobat_vbase + (pbasel & ~gt->gt_iobat_mask);
537 1.1 matt }
538 1.1 matt bs->bs_regions[bs->bs_nregion].br_pbase = pbasel;
539 1.1 matt if (bs->bs_flags & _BUS_SPACE_RELATIVE) {
540 1.1 matt bs->bs_regions[bs->bs_nregion].br_start = 0;
541 1.1 matt bs->bs_regions[bs->bs_nregion].br_end = pbaseh - pbasel;
542 1.1 matt } else {
543 1.1 matt bs->bs_regions[bs->bs_nregion].br_start = pbasel;
544 1.1 matt bs->bs_regions[bs->bs_nregion].br_end = pbaseh;
545 1.1 matt }
546 1.1 matt bs->bs_nregion++;
547 1.1 matt }
548 1.1 matt #endif
549 1.1 matt
550 1.1 matt /*
551 1.1 matt * Internal functions.
552 1.1 matt */
553 1.1 matt int
554 1.1 matt gtpci_bus_maxdevs(pci_chipset_tag_t pc, int busno)
555 1.1 matt {
556 1.1 matt return 32;
557 1.1 matt }
558 1.1 matt
559 1.1 matt pcitag_t
560 1.1 matt gtpci_make_tag(pci_chipset_tag_t pc, int busno, int devno, int funcno)
561 1.1 matt {
562 1.1 matt return PCI_CFG_MAKE_TAG(busno, devno, funcno, 0);
563 1.1 matt }
564 1.1 matt
565 1.1 matt void
566 1.1 matt gtpci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag,
567 1.1 matt int *bp, int *dp, int *fp)
568 1.1 matt {
569 1.1 matt if (bp != NULL)
570 1.1 matt *bp = PCI_CFG_GET_BUSNO(tag);
571 1.1 matt if (dp != NULL)
572 1.1 matt *dp = PCI_CFG_GET_DEVNO(tag);
573 1.1 matt if (fp != NULL)
574 1.1 matt *fp = PCI_CFG_GET_FUNCNO(tag);
575 1.1 matt }
576 1.1 matt
577 1.1 matt pcireg_t
578 1.1 matt gtpci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int regno)
579 1.1 matt {
580 1.1 matt #ifdef DIAGNOSTIC
581 1.1 matt if ((regno & 3) || (regno & ~0xff))
582 1.1 matt panic("gtpci_conf_read: bad regno %#x\n", regno);
583 1.1 matt #endif
584 1.1 matt gtpci_write(pc, pc->pc_md.mdpc_cfgaddr, (int) tag | regno);
585 1.1 matt return gtpci_read(pc, pc->pc_md.mdpc_cfgdata);
586 1.1 matt }
587 1.1 matt
588 1.1 matt void
589 1.1 matt gtpci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int regno, pcireg_t data)
590 1.1 matt {
591 1.1 matt #ifdef DIAGNOSTIC
592 1.1 matt if ((regno & 3) || (regno & ~0xff))
593 1.1 matt panic("gtpci_conf_write: bad regno %#x\n", regno);
594 1.1 matt #endif
595 1.1 matt gtpci_write(pc, pc->pc_md.mdpc_cfgaddr, (int) tag | regno);
596 1.1 matt gtpci_write(pc, pc->pc_md.mdpc_cfgdata, data);
597 1.1 matt }
598 1.1 matt
599 1.1 matt const char *
600 1.1 matt gtpci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t pih)
601 1.1 matt {
602 1.1 matt return intr_string(pih);
603 1.1 matt }
604 1.1 matt
605 1.1 matt const struct evcnt *
606 1.1 matt gtpci_intr_evcnt(pci_chipset_tag_t pc, pci_intr_handle_t pih)
607 1.1 matt {
608 1.1 matt return intr_evcnt(pih);
609 1.1 matt }
610 1.1 matt
611 1.1 matt void *
612 1.1 matt gtpci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t pih,
613 1.1 matt int ipl, int (*handler)(void *), void *arg)
614 1.1 matt {
615 1.1 matt return intr_establish(pih, IST_LEVEL, ipl, handler, arg);
616 1.1 matt }
617 1.1 matt
618 1.1 matt void
619 1.1 matt gtpci_intr_disestablish(pci_chipset_tag_t pc, void *cookie)
620 1.1 matt {
621 1.1 matt intr_disestablish(cookie);
622 1.1 matt }
623