pq3pci.c revision 1.20 1 /* $NetBSD: pq3pci.c,v 1.20 2014/12/27 16:19:33 nonaka Exp $ */
2 /*-
3 * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects
8 * Agency and which was developed by Matt Thomas of 3am Software Foundry.
9 *
10 * This material is based upon work supported by the Defense Advanced Research
11 * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under
12 * Contract No. N66001-09-C-2073.
13 * Approved for Public Release, Distribution Unlimited
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
28 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37 #define PCI_PRIVATE
38 #define GLOBAL_PRIVATE
39 #define __INTR_PRIVATE
40
41 #include "opt_mpc85xx.h"
42 #include "opt_pci.h"
43 #include "locators.h"
44
45 #include <sys/cdefs.h>
46
47 __KERNEL_RCSID(0, "$NetBSD: pq3pci.c,v 1.20 2014/12/27 16:19:33 nonaka Exp $");
48
49 #include <sys/param.h>
50 #include <sys/device.h>
51 #include <sys/cpu.h>
52 #include <sys/intr.h>
53 #include <sys/bus.h>
54 #include <sys/extent.h>
55 #include <sys/bitops.h>
56 #include <sys/kmem.h>
57 #include <sys/malloc.h> /* for extent */
58
59 #include <dev/pci/pcireg.h>
60 #include <dev/pci/pcivar.h>
61 #include <dev/pci/pciconf.h>
62 #include <dev/pci/pcidevs.h>
63
64 #include <powerpc/booke/cpuvar.h>
65 #include <powerpc/booke/spr.h>
66 #include <powerpc/booke/e500var.h>
67 #include <powerpc/booke/e500reg.h>
68 #include <powerpc/booke/openpicreg.h>
69
70 #define PORDEVSR_MPC8536_TRUTH_ENCODE(inst, field, value, result) \
71 TRUTH_ENCODE(SVR_MPC8536v1, inst, PORDEVSR_##field, \
72 __SHIFTIN(field##_##MPC8536##_##value, PORDEVSR_##field), result)
73 #define PORDEVSR_MPC8544_TRUTH_ENCODE(inst, field, value, result) \
74 TRUTH_ENCODE(SVR_MPC8544v1, inst, PORDEVSR_##field, \
75 __SHIFTIN(field##_##MPC8544##_##value, PORDEVSR_##field), result)
76 #define PORDEVSR_MPC8548_TRUTH_ENCODE(inst, field, value, result) \
77 TRUTH_ENCODE(SVR_MPC8548v1, inst, PORDEVSR_##field, \
78 __SHIFTIN(field##_##MPC8548##_##value, PORDEVSR_##field), result)
79 #define PORDEVSR_MPC8555_TRUTH_ENCODE(inst, field, value, result) \
80 TRUTH_ENCODE(SVR_MPC8555v1, inst, PORDEVSR_##field, \
81 __SHIFTIN(field##_##MPC8555##_##value, PORDEVSR_##field), result)
82 #define PORDEVSR_MPC8572_TRUTH_ENCODE(inst, field, value, result) \
83 TRUTH_ENCODE(SVR_MPC8572v1, inst, PORDEVSR_##field, \
84 __SHIFTIN(field##_##MPC8572##_##value, PORDEVSR_##field), result)
85 #define PORDEVSR_P20x0_TRUTH_ENCODE(inst, field, value, result) \
86 TRUTH_ENCODE(SVR_P2020v2, inst, PORDEVSR_##field, \
87 __SHIFTIN(field##_##P20x0##_##value, PORDEVSR_##field), result), \
88 TRUTH_ENCODE(SVR_P2010v2, inst, PORDEVSR_##field, \
89 __SHIFTIN(field##_##P20x0##_##value, PORDEVSR_##field), result)
90 #define PORDEVSR_P1025_TRUTH_ENCODE(inst, field, value, result) \
91 TRUTH_ENCODE(SVR_P1025v1, inst, PORDEVSR_##field, \
92 __SHIFTIN(field##_##P20x0##_##value, PORDEVSR_##field), result), \
93 TRUTH_ENCODE(SVR_P1016v1, inst, PORDEVSR_##field, \
94 __SHIFTIN(field##_##P20x0##_##value, PORDEVSR_##field), result)
95 #define PORDEVSR_P1023_TRUTH_ENCODE(inst, field, value, result) \
96 TRUTH_ENCODE(SVR_P1023v1, inst, PORDEVSR_##field, \
97 __SHIFTIN(field##_##value, PORDEVSR_##field), result), \
98 TRUTH_ENCODE(SVR_P1017v1, inst, PORDEVSR_##field, \
99 __SHIFTIN(field##_##value, PORDEVSR_##field), result)
100
101 #define PORDEVSR_TRUTH_ENCODE(svr, inst, field, value, result) \
102 TRUTH_ENCODE(svr, inst, PORDEVSR_##field, \
103 __SHIFTIN(field##_##value, PORDEVSR_##field), result)
104
105 const struct e500_truthtab pq3pci_pcie_lanes[] = {
106 #ifdef MPC8548
107 PORDEVSR_MPC8548_TRUTH_ENCODE(0, IOSEL, SRIO2500_PCIE1_X4, 4),
108 PORDEVSR_MPC8548_TRUTH_ENCODE(0, IOSEL, SRIO1250_PCIE1_X4, 4),
109 PORDEVSR_MPC8548_TRUTH_ENCODE(0, IOSEL, PCIE1_X8, 8),
110 #endif
111
112 #ifdef MPC8544
113 PORDEVSR_MPC8544_TRUTH_ENCODE(1, IOSEL, PCIE1_ON, 4),
114 PORDEVSR_MPC8544_TRUTH_ENCODE(1, IOSEL, PCIE1_SGMII_ON, 4),
115 PORDEVSR_MPC8544_TRUTH_ENCODE(1, IOSEL, PCIE12_ON, 4),
116 PORDEVSR_MPC8544_TRUTH_ENCODE(1, IOSEL, PCIE12_SGMII_ON, 4),
117 PORDEVSR_MPC8544_TRUTH_ENCODE(1, IOSEL, PCIE123_ON, 4),
118 PORDEVSR_MPC8544_TRUTH_ENCODE(1, IOSEL, PCIE123_SGMII_ON, 4),
119
120 PORDEVSR_MPC8544_TRUTH_ENCODE(2, IOSEL, PCIE12_ON, 4),
121 PORDEVSR_MPC8544_TRUTH_ENCODE(2, IOSEL, PCIE12_SGMII_ON, 4),
122 PORDEVSR_MPC8544_TRUTH_ENCODE(2, IOSEL, PCIE123_ON, 4),
123 PORDEVSR_MPC8544_TRUTH_ENCODE(2, IOSEL, PCIE123_SGMII_ON, 4),
124
125 PORDEVSR_MPC8544_TRUTH_ENCODE(3, IOSEL, PCIE123_ON, 1),
126 PORDEVSR_MPC8544_TRUTH_ENCODE(3, IOSEL, PCIE123_SGMII_ON, 1),
127 #endif
128
129 #ifdef MPC8536
130 PORDEVSR_MPC8536_TRUTH_ENCODE(1, IOSEL, PCIE1_X4, 4),
131 PORDEVSR_MPC8536_TRUTH_ENCODE(1, IOSEL, PCIE1_X8, 8),
132 PORDEVSR_MPC8536_TRUTH_ENCODE(1, IOSEL, PCIE12_X4, 4),
133 PORDEVSR_MPC8536_TRUTH_ENCODE(1, IOSEL, PCIE1_X4_PCI23_X2, 4),
134
135 PORDEVSR_MPC8536_TRUTH_ENCODE(2, IOSEL, PCIE12_X4, 4),
136 PORDEVSR_MPC8536_TRUTH_ENCODE(2, IOSEL, PCIE1_X4_PCI23_X2, 2),
137
138 PORDEVSR_MPC8536_TRUTH_ENCODE(3, IOSEL, PCIE1_X4_PCI23_X2, 2),
139 #endif
140
141 #ifdef MPC8572
142 PORDEVSR_MPC8572_TRUTH_ENCODE(1, IOSEL, SRIO2500_PCIE1_X4, 4),
143 PORDEVSR_MPC8572_TRUTH_ENCODE(1, IOSEL, SRIO1250_PCIE1_X4, 4),
144 PORDEVSR_MPC8572_TRUTH_ENCODE(1, IOSEL, PCIE1_X4, 4),
145 PORDEVSR_MPC8572_TRUTH_ENCODE(1, IOSEL, PCIE12_X4, 4),
146 PORDEVSR_MPC8572_TRUTH_ENCODE(1, IOSEL, PCIE1_X4_23_X2, 4),
147 PORDEVSR_MPC8572_TRUTH_ENCODE(1, IOSEL, PCIE1_X8, 8),
148
149 PORDEVSR_MPC8572_TRUTH_ENCODE(2, IOSEL, PCIE12_X4, 4),
150 PORDEVSR_MPC8572_TRUTH_ENCODE(2, IOSEL, PCIE1_X4_23_X2, 2),
151
152 PORDEVSR_MPC8572_TRUTH_ENCODE(3, IOSEL, PCIE1_X4_23_X2, 2),
153 #endif
154
155 #ifdef P2020
156 PORDEVSR_P20x0_TRUTH_ENCODE(1, IOSEL, PCIE1_X1, 1),
157 PORDEVSR_P20x0_TRUTH_ENCODE(1, IOSEL, PCIE12_X1_3_X2, 1),
158 PORDEVSR_P20x0_TRUTH_ENCODE(1, IOSEL, PCIE13_X2, 2),
159 PORDEVSR_P20x0_TRUTH_ENCODE(1, IOSEL, PCIE1_X4, 4),
160 PORDEVSR_P20x0_TRUTH_ENCODE(1, IOSEL, PCIE1_X1_SRIO2500_1X, 1),
161 PORDEVSR_P20x0_TRUTH_ENCODE(1, IOSEL, PCIE12_X1_SGMII23, 1),
162 PORDEVSR_P20x0_TRUTH_ENCODE(1, IOSEL, PCIE1_X2_SGMII23, 2),
163
164 PORDEVSR_P20x0_TRUTH_ENCODE(2, IOSEL, PCIE12_X1_3_X2, 1),
165 PORDEVSR_P20x0_TRUTH_ENCODE(2, IOSEL, PCIE12_X1_SGMII23, 1),
166
167 PORDEVSR_P20x0_TRUTH_ENCODE(3, IOSEL, PCIE12_X1_3_X2, 2),
168 PORDEVSR_P20x0_TRUTH_ENCODE(3, IOSEL, PCIE13_X2, 2),
169 #endif
170
171 #ifdef P1025
172 PORDEVSR_P1025_TRUTH_ENCODE(1, IOSEL, PCIE1_X1, 1),
173 PORDEVSR_P1025_TRUTH_ENCODE(1, IOSEL, PCIE1_X4, 4),
174 PORDEVSR_P1025_TRUTH_ENCODE(1, IOSEL, PCIE12_X1_SGMII23, 1),
175 PORDEVSR_P1025_TRUTH_ENCODE(1, IOSEL, PCIE1_X2_SGMII23, 2),
176
177 PORDEVSR_P1025_TRUTH_ENCODE(2, IOSEL, PCIE12_X1_SGMII23, 1),
178 #endif
179
180 #ifdef P1023
181 PORDEVSR_P1023_TRUTH_ENCODE(1, IOSEL_P1023, PCIE12_X1, 1),
182 PORDEVSR_P1023_TRUTH_ENCODE(1, IOSEL_P1023, PCIE123_X1, 1),
183 PORDEVSR_P1023_TRUTH_ENCODE(1, IOSEL_P1023, PCIE123_X1_SGMII2, 1),
184 PORDEVSR_P1023_TRUTH_ENCODE(1, IOSEL_P1023, PCIE12_X1_SGMII12, 1),
185
186 PORDEVSR_P1023_TRUTH_ENCODE(2, IOSEL_P1023, PCIE12_X1, 1),
187 PORDEVSR_P1023_TRUTH_ENCODE(2, IOSEL_P1023, PCIE123_X1, 1),
188 PORDEVSR_P1023_TRUTH_ENCODE(2, IOSEL_P1023, PCIE123_X1_SGMII2, 1),
189 PORDEVSR_P1023_TRUTH_ENCODE(2, IOSEL_P1023, PCIE12_X1_SGMII12, 1),
190
191 PORDEVSR_P1023_TRUTH_ENCODE(3, IOSEL_P1023, PCIE123_X1, 1),
192 PORDEVSR_P1023_TRUTH_ENCODE(3, IOSEL_P1023, PCIE123_X1_SGMII2, 1),
193 #endif
194 };
195
196 static const struct e500_truthtab pq3pci_pci_pcix[] = {
197 #ifdef MPC8548
198 PORDEVSR_TRUTH_ENCODE(SVR_MPC8548v1, 1, PCI1, PCIX, 1),
199 #endif
200 };
201
202 static const struct e500_truthtab pq3pci_pci_pci32[] = {
203 #ifdef MPC8548
204 PORDEVSR_TRUTH_ENCODE(SVR_MPC8548v1, 1, PCI32, FALSE, 64),
205 PORDEVSR_TRUTH_ENCODE(SVR_MPC8548v1, 1, PCI32, TRUE, 32),
206 #endif
207
208 #ifdef MPC8555
209 PORDEVSR_TRUTH_ENCODE(SVR_MPC8555v1, 0, PCI32, FALSE, 64),
210 PORDEVSR_TRUTH_ENCODE(SVR_MPC8555v1, 0, PCI32, TRUE, 32),
211 #endif
212 };
213
214 struct pq3pci_bst {
215 struct powerpc_bus_space bs_tag;
216 uint8_t bs_numwin;
217 bus_addr_t bs_base[3];
218 bus_addr_t bs_offset[3];
219 bus_addr_t bs_limit[3];
220 char bs_name[16];
221 char bs_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8)] __aligned(8);
222 };
223
224 typedef enum { IH_NONE, IH_INTX, IH_MSI, IH_MSIX } pq3pci_intr_class_t;
225
226 struct pq3pci_genihand {
227 pq3pci_intr_class_t ih_class;
228 int (*ih_func)(void *);
229 void *ih_arg;
230 struct pq3pci_softc *ih_sc;
231 };
232
233 struct pq3pci_intrhand {
234 struct pq3pci_genihand pih_ih;
235 SIMPLEQ_ENTRY(pq3pci_intrhand) pih_link;
236 int pih_ipl;
237 struct pq3pci_intrsource *pih_source;
238 uint64_t pih_count;
239 };
240
241 struct pq3pci_callhand {
242 struct pq3pci_genihand pch_ih;
243 struct callout pch_callout;
244 int pch_ipl;
245 };
246
247 #define PIH_MAKE(irq, ist, nmsi) (((nmsi) << 20) | ((irq) << 8) | (ist))
248 #define PIH_IST(pih) (((pih) >> 0) & 0xff)
249 #define PIH_IRQ(pih) (((pih) >> 8) & 0xfff)
250 #define PIH_NMSI(pih) (((pih) >> 20) & 0xff)
251
252 struct pq3pci_intrsource {
253 SIMPLEQ_ENTRY(pq3pci_intrsource) pis_link;
254 SIMPLEQ_HEAD(,pq3pci_intrhand) pis_ihands;
255 struct evcnt pis_ev;
256 struct evcnt pis_ev_spurious;
257 kmutex_t *pis_lock;
258 pci_intr_handle_t pis_handle;
259 void *pis_ih;
260 };
261
262 struct pq3pci_msihand {
263 struct pq3pci_genihand msih_ih;
264 struct pq3pci_msigroup *msih_group;
265 struct evcnt msih_ev;
266 struct evcnt msih_ev_spurious;
267 pcitag_t msih_tag;
268 int msih_msioff;
269 };
270
271 struct pq3pci_msigroup {
272 kmutex_t *msig_lock;
273 void *msig_ih;
274 uint32_t msig_free_mask;
275 int msig_ipl;
276 u_int msig_group;
277 bus_size_t msig_msir;
278 struct pq3pci_msihand msig_ihands[32];
279 };
280
281 struct pq3pci_softc {
282 device_t sc_dev;
283 bus_space_tag_t sc_bst;
284 bus_space_handle_t sc_bsh;
285 void *sc_ih;
286 bool sc_pcie;
287 struct genppc_pci_chipset sc_pc;
288 struct pq3pci_bst sc_pci_io_bst;
289 struct pq3pci_bst sc_pci_mem_bst;
290 u_int sc_pba_flags;
291 kmutex_t *sc_conf_lock;
292 kmutex_t *sc_intr_lock;
293 struct evcnt sc_ev_spurious;
294 prop_dictionary_t sc_intrmap;
295 uint32_t sc_intrmask;
296 };
297
298 static int pq3pci_cpunode_match(device_t, cfdata_t, void *aux);
299 static void pq3pci_cpunode_attach(device_t, device_t, void *aux);
300 static pci_chipset_tag_t pq3pci_pci_chipset_init(struct pq3pci_softc *);
301
302 static SIMPLEQ_HEAD(,pq3pci_intrsource) pq3pci_intrsources
303 = SIMPLEQ_HEAD_INITIALIZER(pq3pci_intrsources);
304 static struct pq3pci_msigroup *pq3pci_msigroups[8];
305
306 static struct pq3pci_intrsource *
307 pq3pci_intr_source_lookup(struct pq3pci_softc *, pci_intr_handle_t);
308
309 static const char msi_intr_names[8][32][8] = {
310 {
311 "msi 0", "msi 1", "msi 2", "msi 3",
312 "msi 4", "msi 5", "msi 6", "msi 7",
313 "msi 8", "msi 9", "msi 10", "msi 11",
314 "msi 12", "msi 13", "msi 14", "msi 15",
315 "msi 16", "msi 17", "msi 18", "msi 19",
316 "msi 20", "msi 21", "msi 22", "msi 23",
317 "msi 24", "msi 25", "msi 26", "msi 27",
318 "msi 28", "msi 29", "msi 30", "msi 31",
319 }, {
320 "msi 32", "msi 33", "msi 34", "msi 35",
321 "msi 36", "msi 37", "msi 38", "msi 39",
322 "msi 40", "msi 41", "msi 42", "msi 43",
323 "msi 44", "msi 45", "msi 46", "msi 47",
324 "msi 48", "msi 49", "msi 50", "msi 51",
325 "msi 52", "msi 53", "msi 54", "msi 55",
326 "msi 56", "msi 57", "msi 58", "msi 59",
327 "msi 60", "msi 61", "msi 62", "msi 63",
328 }, {
329 "msi 64", "msi 65", "msi 66", "msi 67",
330 "msi 68", "msi 69", "msi 70", "msi 71",
331 "msi 72", "msi 73", "msi 74", "msi 75",
332 "msi 76", "msi 77", "msi 78", "msi 79",
333 "msi 80", "msi 81", "msi 82", "msi 83",
334 "msi 84", "msi 85", "msi 86", "msi 87",
335 "msi 88", "msi 89", "msi 90", "msi 91",
336 "msi 92", "msi 93", "msi 94", "msi 95",
337 }, {
338 "msi 96", "msi 97", "msi 98", "msi 99",
339 "msi 100", "msi 101", "msi 102", "msi 103",
340 "msi 104", "msi 105", "msi 106", "msi 107",
341 "msi 108", "msi 109", "msi 110", "msi 111",
342 "msi 112", "msi 113", "msi 114", "msi 115",
343 "msi 116", "msi 117", "msi 118", "msi 119",
344 "msi 120", "msi 121", "msi 122", "msi 123",
345 "msi 124", "msi 125", "msi 126", "msi 127",
346 }, {
347 "msi 128", "msi 129", "msi 130", "msi 131",
348 "msi 132", "msi 133", "msi 134", "msi 135",
349 "msi 136", "msi 137", "msi 138", "msi 139",
350 "msi 140", "msi 141", "msi 142", "msi 143",
351 "msi 144", "msi 145", "msi 146", "msi 147",
352 "msi 148", "msi 149", "msi 150", "msi 151",
353 "msi 152", "msi 153", "msi 154", "msi 155",
354 "msi 156", "msi 157", "msi 158", "msi 159",
355 }, {
356 "msi 160", "msi 161", "msi 162", "msi 163",
357 "msi 164", "msi 165", "msi 166", "msi 167",
358 "msi 168", "msi 169", "msi 170", "msi 171",
359 "msi 172", "msi 173", "msi 174", "msi 175",
360 "msi 176", "msi 177", "msi 178", "msi 179",
361 "msi 180", "msi 181", "msi 182", "msi 183",
362 "msi 184", "msi 185", "msi 186", "msi 187",
363 "msi 188", "msi 189", "msi 190", "msi 191",
364 }, {
365 "msi 192", "msi 193", "msi 194", "msi 195",
366 "msi 196", "msi 197", "msi 198", "msi 199",
367 "msi 200", "msi 201", "msi 202", "msi 203",
368 "msi 204", "msi 205", "msi 206", "msi 207",
369 "msi 208", "msi 209", "msi 210", "msi 211",
370 "msi 212", "msi 213", "msi 214", "msi 215",
371 "msi 216", "msi 217", "msi 218", "msi 219",
372 "msi 220", "msi 221", "msi 222", "msi 223",
373 }, {
374 "msi 224", "msi 225", "msi 226", "msi 227",
375 "msi 228", "msi 229", "msi 230", "msi 231",
376 "msi 232", "msi 233", "msi 234", "msi 235",
377 "msi 236", "msi 237", "msi 238", "msi 239",
378 "msi 240", "msi 241", "msi 242", "msi 243",
379 "msi 244", "msi 245", "msi 246", "msi 247",
380 "msi 248", "msi 249", "msi 250", "msi 251",
381 "msi 252", "msi 253", "msi 254", "msi 255",
382 },
383 };
384
385 CFATTACH_DECL_NEW(pq3pci_cpunode, sizeof(struct pq3pci_softc),
386 pq3pci_cpunode_match, pq3pci_cpunode_attach, NULL, NULL);
387
388 CFATTACH_DECL_NEW(pq3pcie_cpunode, sizeof(struct pq3pci_softc),
389 pq3pci_cpunode_match, pq3pci_cpunode_attach, NULL, NULL);
390
391 int
392 pq3pci_cpunode_match(device_t parent, cfdata_t cf, void *aux)
393 {
394
395 if (!e500_cpunode_submatch(parent, cf, cf->cf_name + 3, aux))
396 return 0;
397
398 return 1;
399 }
400
401 struct pq3pci_owin {
402 uint32_t potar;
403 uint32_t potear;
404 uint32_t powbar;
405 uint32_t powar;
406 };
407
408 static void
409 pq3pci_owin_record(struct pq3pci_softc *sc, u_int winnum,
410 const struct pq3pci_owin *owin)
411 {
412 const bool io_win = (owin->powar & PEXOWAR_RTT) == PEXOWAR_RTT_IO;
413 struct pq3pci_bst *bs = io_win ? &sc->sc_pci_io_bst : &sc->sc_pci_mem_bst;
414 const uint64_t pci_base = ((uint64_t)owin->potar << 12)
415 | ((uint64_t)owin->potear << (32+12));
416 const uint64_t local_base = (uint64_t)owin->powbar << 12;
417 const u_int win_size_log2 = PEXIWAR_IWS_GET(owin->powar) + 1;
418 u_int slot;
419
420 bs->bs_tag.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN
421 | (io_win ? _BUS_SPACE_IO_TYPE : _BUS_SPACE_MEM_TYPE);
422
423 for (slot = 0; slot < bs->bs_numwin; slot++) {
424 if (pci_base < bs->bs_base[slot]) {
425 for (size_t j = slot; j < bs->bs_numwin; j++) {
426 bs->bs_base[j+1] = bs->bs_base[j];
427 bs->bs_offset[j+1] = bs->bs_offset[j];
428 bs->bs_limit[j+1] = bs->bs_limit[j];
429 }
430 break;
431 }
432 }
433 bs->bs_base[slot] = pci_base;
434 bs->bs_offset[slot] = local_base - pci_base;
435 bs->bs_limit[slot] = pci_base + (1ULL << win_size_log2);
436 bs->bs_numwin++;
437
438 #if 0
439 const char units[] = " KMGTP";
440 aprint_normal_dev(sc->sc_dev,
441 "outbound window %u: potar=%#x, potear=%#x, powbar=%x, powar=%#x\n",
442 winnum, owin->potar, owin->potear, owin->powbar, owin->powar);
443 aprint_normal_dev(sc->sc_dev,
444 "outbound window %u: maps %u%cB of PCI %s space @ %#"PRIx64" onto local addresses @ %#"PRIx64".\n",
445 winnum, 1 << (win_size_log2 % 10), units[win_size_log2 / 10],
446 (owin->powar & PEXOWAR_RTT) == PEXOWAR_RTT_IO ? "I/O" : "memory",
447 local_base, pci_base);
448 #endif
449 }
450
451 static bool
452 pq3pci_owin_init(struct pq3pci_softc *sc, struct pq3pci_bst *bs, bool io_win)
453 {
454 if (bs->bs_numwin == 0)
455 return true;
456
457 bs->bs_tag.pbs_base = bs->bs_base[0];
458 bs->bs_tag.pbs_offset = bs->bs_offset[0];
459 bs->bs_tag.pbs_limit = bs->bs_limit[bs->bs_numwin - 1];
460
461 snprintf(bs->bs_name, sizeof(bs->bs_name), "%s-%s",
462 device_xname(sc->sc_dev), io_win ? "io" : "mem");
463
464 #if 0
465 printf("%s: %s: base=%#x offset=%#x limit=%#x\n", __func__, bs->bs_name,
466 bs->bs_tag.pbs_base, bs->bs_tag.pbs_offset, bs->bs_tag.pbs_limit);
467 #endif
468
469 int error = bus_space_init(&bs->bs_tag, bs->bs_name,
470 bs->bs_ex_storage, sizeof(bs->bs_ex_storage));
471 if (error) {
472 aprint_error(": failed to create %s bus space: %d\n",
473 bs->bs_name, error);
474 return false;
475 }
476 for (size_t slot = 1; slot < bs->bs_numwin; slot++) {
477 if (bs->bs_limit[slot - 1] < bs->bs_base[slot]) {
478 error = extent_alloc_region(bs->bs_tag.pbs_extent,
479 bs->bs_limit[slot - 1],
480 bs->bs_base[slot] - bs->bs_limit[slot - 1],
481 EX_WAITOK);
482 if (error) {
483 aprint_error(": failed to hole in %s bus space: %d\n",
484 bs->bs_name, error);
485 return false;
486 }
487 }
488 }
489 aprint_debug_dev(sc->sc_dev, "bus space %s created\n", bs->bs_name);
490 sc->sc_pba_flags |=
491 io_win ? PCI_FLAGS_IO_OKAY : PCI_FLAGS_MEM_OKAY;
492 return true;
493 }
494
495 struct pq3pci_iwin {
496 uint32_t pitar;
497 uint32_t piwbar;
498 uint32_t piwbear;
499 uint32_t piwar;
500 };
501
502 static bool
503 pq3pci_iwin_setup(struct pq3pci_softc *sc, u_int winnum,
504 const struct pq3pci_iwin *iwin)
505 {
506 const uint64_t pci_base = ((uint64_t)iwin->piwbar << 12)
507 | ((uint64_t)iwin->piwbear << (32+12));
508 const uint64_t local_base = (uint64_t)iwin->pitar << 12;
509 const u_int win_size_log2 = PEXIWAR_IWS_GET(iwin->piwar) + 1;
510 #if DEBUG > 1
511 const char units[] = " KMGTP";
512 aprint_normal_dev(sc->sc_dev,
513 "inbound window %u: pitar=%#x, piwbar=%x, piwbear=%#x, piwar=%#x\n",
514 winnum, iwin->pitar, iwin->piwbar, iwin->piwbear, iwin->piwar);
515 aprint_normal_dev(sc->sc_dev,
516 "inbound window %u: maps %u%cB of PCI address space @ %#"PRIx64" to local memory @ %#"PRIx64".\n",
517 winnum, 1 << (win_size_log2 % 10), units[win_size_log2 / 10],
518 pci_base, local_base);
519 #endif /* DEBUG */
520 /*
521 * Let's make sure this window is usable.
522 */
523 if (pci_base != 0) {
524 aprint_error(": invalid inbound window: "
525 "PCI base (%#"PRIx64" != 0\n", pci_base);
526 return false;
527 }
528 if (local_base != 0) {
529 aprint_error(": invalid inbound window: "
530 "local base (%#"PRIx64" != 0\n", local_base);
531 return false;
532 }
533 if ((iwin->piwar & PEXIWAR_RTT) != PEXIWAR_RTT_MEM_SNOOP) {
534 aprint_error(": invalid inbound window: "
535 "unsupported read transaction type (%#"PRIxMAX")\n",
536 iwin->piwar & PEXIWAR_RTT);
537 return false;
538 }
539 if ((iwin->piwar & PEXIWAR_WTT) != PEXIWAR_WTT_MEM_SNOOP) {
540 aprint_error(": invalid inbound window: "
541 "unsupported write transaction type (%#"PRIxMAX")\n",
542 iwin->piwar & PEXIWAR_WTT);
543 return false;
544 }
545 if ((iwin->piwar & PEXIWAR_TRGT) != PEXIWAR_TRGT_LOCALMEM) {
546 aprint_error(": invalid inbound window: "
547 "unsupported target (%#"PRIxMAX")\n",
548 iwin->piwar & PEXIWAR_TRGT);
549 return false;
550 }
551 if (board_info_get_number("mem-size") > (1ULL << win_size_log2)) {
552 aprint_error(": invalid inbound window: "
553 "doesn't map all of memory (%#"PRIx64" < %#"PRIx64")\n",
554 1ULL << win_size_log2, board_info_get_number("mem-size"));
555 return false;
556 }
557 return true;
558 }
559
560 static void
561 pq3pci_pch_callout(void *v)
562 {
563 struct pq3pci_callhand * const pch = v;
564
565 int s = splraise(pch->pch_ipl);
566 (*pch->pch_ih.ih_func)(pch->pch_ih.ih_arg);
567 splx(s);
568 callout_schedule(&pch->pch_callout, 1);
569 }
570
571 static int
572 pq3pci_msi_spurious_intr(void *v)
573 {
574 (void) v;
575
576 return 0;
577 }
578
579 static int
580 pq3pci_msi_intr(void *v)
581 {
582 struct pq3pci_msigroup * const msig = v;
583
584 mutex_spin_enter(msig->msig_lock);
585 KASSERT(curcpu()->ci_cpl == msig->msig_ipl);
586 //KASSERT(curcpu()->ci_idepth == 0);
587 uint32_t matches = 0;
588 for (int rv = 0;;) {
589 uint32_t group = cpu_read_4(msig->msig_msir);
590 if (group == 0) {
591 mutex_spin_exit(msig->msig_lock);
592 return rv;
593 }
594
595 const bool working_msi_p =
596 msig->msig_group != 0 || (group & 1) == 0;
597 if (working_msi_p) {
598 /*
599 * if MSIs are working, just clear the free MSIs.
600 */
601 KASSERTMSG((group & msig->msig_free_mask) == 0,
602 "%s: group#%u: unexpected MSIs (%#x)",
603 __func__, msig->msig_group,
604 group & msig->msig_free_mask);
605 group &= ~msig->msig_free_mask;
606 } else {
607 /*
608 * If MSIs are broken, we don't really what MSIs
609 * have happened.
610 */
611 for (struct pq3pci_msihand *msih = msig->msig_ihands + 31;
612 group != 0;
613 msih--) {
614 const u_int n = __builtin_clz(group);
615 msih -= n;
616 group <<= n + 1;
617 msih->msih_ev.ev_count++;
618 }
619 group = ~msig->msig_free_mask;
620 }
621 uint32_t this_msi = __BIT(31);
622 for (struct pq3pci_msihand *msih = msig->msig_ihands + 31;
623 group != 0;
624 msih--) {
625 KASSERT(msig->msig_ihands <= msih);
626 KASSERT(msih < &msig->msig_ihands[32]);
627 const u_int n = __builtin_clz(group);
628 msih -= n;
629 group <<= n + 1;
630 msih->msih_ev.ev_count += working_msi_p;
631 if ((*msih->msih_ih.ih_func)(msih->msih_ih.ih_arg)) {
632 rv = 1;
633 msih->msih_ev.ev_count += !working_msi_p;
634 matches |= this_msi;
635 } else if ((matches & this_msi) == 0) {
636 msih->msih_ev_spurious.ev_count += working_msi_p;
637 }
638 this_msi >>= n + 1;
639 }
640 }
641 }
642
643 static int
644 pq3pci_onchip_intr(void *v)
645 {
646 panic(__func__);
647 }
648
649 static int
650 pq3pci_pis_intr(void *v)
651 {
652 struct pq3pci_intrsource * const pis = v;
653 struct pq3pci_intrhand *pih;
654 int rv = 0;
655
656 mutex_spin_enter(pis->pis_lock);
657 pis->pis_ev.ev_count++;
658 SIMPLEQ_FOREACH(pih, &pis->pis_ihands, pih_link) {
659 struct pq3pci_softc * const sc = pih->pih_ih.ih_sc;
660 int s = splraise(pih->pih_ipl);
661 pih->pih_count++;
662 rv = (*pih->pih_ih.ih_func)(pih->pih_ih.ih_arg);
663 splx(s);
664 #if 0
665 printf("%s %d:%s %"PRIu64": %p(%p) %"PRIu64": %d\n", __func__,
666 curcpu()->ci_idepth,
667 pis->pis_ev.ev_group, pis->pis_ev.ev_count,
668 pih->pih_ih.ih_func, pih->pih_ih.ih_arg, pih->pih_count, rv);
669 #endif
670 if (rv != 0) {
671 bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCI_INT_ACK);
672 break;
673 }
674 pih->pih_count--;
675 }
676 if (rv == 0)
677 pis->pis_ev_spurious.ev_count++;
678 mutex_spin_exit(pis->pis_lock);
679 return rv;
680 }
681
682 static void
683 pq3pci_intr_source_setup(struct pq3pci_softc *sc,
684 struct pq3pci_intrsource *pis, pci_intr_handle_t handle)
685 {
686 char buf[PCI_INTRSTR_LEN];
687 SIMPLEQ_INIT(&pis->pis_ihands);
688 pis->pis_handle = handle;
689 pis->pis_ih = intr_establish(PIH_IRQ(handle), IPL_VM, PIH_IST(handle),
690 pq3pci_pis_intr, pis);
691 pis->pis_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_VM);
692 const char * const intrstr
693 = intr_string(PIH_IRQ(handle), PIH_IST(handle), buf, sizeof(buf));
694 evcnt_attach_dynamic(&pis->pis_ev, EVCNT_TYPE_INTR,
695 NULL, intrstr, "intr");
696 evcnt_attach_dynamic(&pis->pis_ev_spurious, EVCNT_TYPE_INTR,
697 &pis->pis_ev, intrstr, "spurious intr");
698 SIMPLEQ_INSERT_TAIL(&pq3pci_intrsources, pis, pis_link);
699 }
700
701 static bool
702 pq3pci_intrmap_setup(struct pq3pci_softc *sc,
703 const struct cpunode_locators *cnl)
704 {
705 char prop_name[32];
706 snprintf(prop_name, sizeof(prop_name), "%s%u-interrupt-map",
707 cnl->cnl_name, cnl->cnl_instance);
708 sc->sc_intrmap = board_info_get_object(prop_name);
709 if (sc->sc_intrmap == NULL) {
710 aprint_error(": missing %s board property", prop_name);
711 return false;
712 }
713
714 KASSERT(prop_object_type(sc->sc_intrmap) == PROP_TYPE_DICTIONARY);
715 prop_number_t pn = prop_dictionary_get(sc->sc_intrmap, "interrupt-mask");
716 KASSERT(pn != NULL);
717
718 sc->sc_intrmask = prop_number_unsigned_integer_value(pn);
719
720 sc->sc_ih = intr_establish(cnl->cnl_intrs[0], IPL_VM, IST_ONCHIP,
721 pq3pci_onchip_intr, sc);
722 if (sc->sc_ih == NULL)
723 panic("%s: failed to establish interrupt %d\n",
724 device_xname(sc->sc_dev), cnl->cnl_intrs[0]);
725
726 return true;
727 }
728
729 void
730 pq3pci_cpunode_attach(device_t parent, device_t self, void *aux)
731 {
732 struct cpunode_softc * const psc = device_private(parent);
733 struct pq3pci_softc * const sc = device_private(self);
734 struct cpunode_attach_args * const cna = aux;
735 struct cpunode_locators * const cnl = &cna->cna_locs;
736 char buf[32];
737
738 sc->sc_dev = self;
739 sc->sc_bst = cna->cna_memt;
740 psc->sc_children |= cna->cna_childmask;
741 sc->sc_pcie = strcmp(cnl->cnl_name, "pcie") == 0;
742
743 const uint32_t pordevsr = cpu_read_4(GLOBAL_BASE + PORDEVSR);
744 if (sc->sc_pcie) {
745 u_int lanes = e500_truth_decode(cnl->cnl_instance, pordevsr,
746 pq3pci_pcie_lanes, __arraycount(pq3pci_pcie_lanes), 0);
747 if (lanes == 0) {
748 aprint_normal(": disabled\n");
749 return;
750 }
751 snprintf(buf, sizeof(buf), "PCI-Express x%u", lanes);
752 } else {
753 bool pcix_p = e500_truth_decode(cnl->cnl_instance, pordevsr,
754 pq3pci_pci_pcix, __arraycount(pq3pci_pci_pcix), 0);
755 u_int width = e500_truth_decode(cnl->cnl_instance, pordevsr,
756 pq3pci_pci_pci32, __arraycount(pq3pci_pci_pci32), 32);
757 snprintf(buf, sizeof(buf), "%u-bit PCI%s",
758 width, (pcix_p ? "X" : ""));
759 }
760
761 if (!pq3pci_intrmap_setup(sc, cnl))
762 return;
763
764 evcnt_attach_dynamic(&sc->sc_ev_spurious, EVCNT_TYPE_INTR, NULL,
765 device_xname(self), "spurious intr");
766
767 int error = bus_space_map(sc->sc_bst, cnl->cnl_addr, cnl->cnl_size, 0,
768 &sc->sc_bsh);
769 if (error) {
770 aprint_error(": failed to map registers: %d\n", error);
771 return;
772 }
773
774 u_int valid_owins = 0;
775 for (u_int i = 1, off = PEXOTAR1 - PEXOTAR0;
776 i < 4; i++, off += PEXOTAR1 - PEXOTAR0) {
777 struct pq3pci_owin owin;
778 owin.potar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
779 PEXOTAR0 + off);
780 owin.potear = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
781 PEXOTEAR0 + off);
782 owin.powbar = 0;
783 if (i > 0) {
784 /* Doesn't exist for outbound window 0 */
785 owin.powbar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
786 PEXOWBAR1 - (PEXOTAR1 - PEXOTAR0) + off);
787 }
788 owin.powar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
789 PEXOWAR0 + off);
790 #if 0
791 aprint_normal_dev(self,
792 "owin[%u]: potar=%#x potear=%#x powbar=%#x powar=%#x\n",
793 i, owin.potar, owin.potear, owin.powbar, owin.powar);
794 #endif
795 if (owin.powar & PEXOWAR_EN) {
796 valid_owins++;
797 pq3pci_owin_record(sc, i, &owin);
798 }
799 }
800 if (!pq3pci_owin_init(sc, &sc->sc_pci_io_bst, true)
801 || !pq3pci_owin_init(sc, &sc->sc_pci_mem_bst, false)) {
802 return;
803 }
804 #ifndef PCI_NETBSD_CONFIGURE
805 if (valid_owins == 0) {
806 aprint_normal(": %s controller%s\n", buf,
807 " (disabled)");
808 return;
809 }
810 #endif
811
812 u_int valid_iwins = 0;
813 for (u_int i = 0, off = 0; i < 3; i++, off += PEXITAR2 - PEXITAR1) {
814 struct pq3pci_iwin iwin;
815 iwin.pitar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
816 PEXITAR1 + off);
817 iwin.piwbar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
818 PEXIWBAR1 + off);
819 if (i > 0) {
820 /* Doesn't exist */
821 iwin.piwbear = bus_space_read_4(sc->sc_bst,
822 sc->sc_bsh,
823 PEXIWBEAR2 - (PEXITAR2 - PEXITAR1) + off);
824 } else {
825 iwin.piwbear = 0;
826 }
827 iwin.piwar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
828 PEXIWAR1 + off);
829 #if 0
830 aprint_normal_dev(self,
831 "iwin[%u]: pitar=%#x piwbar=%#x piwbear=%#x piwar=%#x\n",
832 i, iwin.pitar, iwin.piwbar, iwin.piwbear, iwin.piwar);
833 #endif
834 if (iwin.piwar & PEXIWAR_EN) {
835 valid_iwins++;
836 if (!pq3pci_iwin_setup(sc, i, &iwin))
837 return;
838 }
839 }
840
841 sc->sc_conf_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_VM);
842
843 pci_chipset_tag_t pc = pq3pci_pci_chipset_init(sc);
844
845 #ifndef PCI_NETBSD_CONFIGURE
846 if (valid_iwins == 0) {
847 aprint_normal(": %s controller%s\n", buf,
848 " (disabled)");
849 return;
850 }
851 #else
852 if (sc->sc_pcie && pci_conf_read(pc, 0, PEX_LTSSM) < LTSSM_L0) {
853 aprint_normal(": %s controller%s\n", buf,
854 " (offline)");
855 return;
856 }
857 if (!sc->sc_pcie && (pci_conf_read(pc, 0, PCI_PBFR) & PBFR_PAH)) {
858 aprint_normal(": %s controller%s\n", buf,
859 " (agent mode)");
860 return;
861 }
862 if (valid_iwins == 0) {
863 struct pq3pci_iwin iwin = {
864 .pitar = 0,
865 .piwbar = 0,
866 .piwbear = 0,
867 .piwar = PEXIWAR_EN|PEXIWAR_PF|PEXIWAR_TRGT_LOCALMEM
868 |PEXIWAR_RTT_MEM_SNOOP|PEXIWAR_WTT_MEM_SNOOP
869 |__SHIFTIN(30-__builtin_clz(pmemsize),PEXIWAR_IWS),
870 };
871 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXITAR2, iwin.pitar);
872 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWBAR2, iwin.piwbar);
873 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWBEAR2, iwin.piwbear);
874 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWAR2, iwin.piwar);
875
876 if (!pq3pci_iwin_setup(sc, 2, &iwin)) {
877 aprint_error(": error creating inbound window\n");
878 return;
879 }
880
881 }
882
883 if (valid_owins == 0) {
884 u_long membase, iobase;
885 error = extent_alloc(pcimem_ex, PCI_MEMSIZE, PCI_MEMSIZE,
886 PCI_MEMSIZE, EX_WAITOK, &membase);
887 if (error) {
888 aprint_error(
889 ": error allocating address space for %s: %d\n",
890 "PCI memory", error);
891 return;
892 }
893 struct pq3pci_owin owin1 = {
894 .potar = membase >> 12,
895 .potear = 0,
896 .powbar = membase >> 12,
897 .powar = PEXOWAR_EN|PEXOWAR_TC0
898 |PEXOWAR_RTT_MEM|PEXOWAR_WTT_MEM
899 |__SHIFTIN(ilog2(PCI_MEMSIZE)-1,PEXOWAR_OWS),
900 };
901 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTAR1, owin1.potar);
902 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTEAR1, owin1.potear);
903 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWBAR1, owin1.powbar);
904 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWAR1, owin1.powar);
905 pq3pci_owin_record(sc, 1, &owin1);
906 if (!pq3pci_owin_init(sc, &sc->sc_pci_mem_bst, false)) {
907 return;
908 }
909
910 error = extent_alloc(pciio_ex, PCI_IOSIZE, PCI_IOSIZE,
911 PCI_IOSIZE, EX_WAITOK, &iobase);
912 if (error) {
913 aprint_error(
914 ": error allocating address space for %s: %d\n",
915 "PCI I/O space", error);
916 return;
917 }
918 struct pq3pci_owin owin2 = {
919 .potar = 0,
920 .potear = 0,
921 .powbar = iobase >> 12,
922 .powar = PEXOWAR_EN|PEXOWAR_TC0
923 |PEXOWAR_RTT_IO|PEXOWAR_WTT_IO
924 |__SHIFTIN(ilog2(PCI_IOSIZE)-1,PEXOWAR_OWS),
925 };
926 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTAR2, owin2.potar);
927 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTEAR2, owin2.potear);
928 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWBAR2, owin2.powbar);
929 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWAR2, owin2.powar);
930 pq3pci_owin_record(sc, 2, &owin1);
931 if (!pq3pci_owin_init(sc, &sc->sc_pci_io_bst, true)) {
932 return;
933 }
934
935 struct extent *ioext = extent_create("pciio", 0, PCI_IOSIZE,
936 NULL, 0, EX_NOWAIT);
937 struct extent *memext = extent_create("pcimem", membase,
938 membase + PCI_MEMSIZE, NULL, 0, EX_NOWAIT);
939
940 error = pci_configure_bus(pc, ioext, memext, NULL, 0,
941 curcpu()->ci_ci.dcache_line_size);
942
943 extent_destroy(ioext);
944 extent_destroy(memext);
945
946 if (error) {
947 aprint_normal(": configuration failed\n");
948 return;
949 }
950 }
951 #endif
952
953 aprint_normal(": %s controller%s\n", buf, "");
954
955 struct pcibus_attach_args pba;
956 memset(&pba, 0, sizeof(pba));
957
958 pba.pba_flags = sc->sc_pba_flags | PCI_FLAGS_MSI_OKAY
959 | PCI_FLAGS_MSIX_OKAY;
960 if (pba.pba_flags & PCI_FLAGS_IO_OKAY)
961 pba.pba_iot = pc->pc_iot;
962 if (pba.pba_flags & PCI_FLAGS_MEM_OKAY)
963 pba.pba_memt = pc->pc_memt;
964 pba.pba_dmat = cna->cna_dmat;
965 pba.pba_pc = pc;
966 pba.pba_bus = 0;
967
968 /*
969 * Program BAR0 so that MSIs can work.
970 */
971 pci_conf_write(pc, 0, PCI_BAR0, sc->sc_bst->pbs_offset);
972 pcireg_t cmdsts = pci_conf_read(pc, 0, PCI_COMMAND_STATUS_REG);
973 cmdsts |= PCI_COMMAND_INTERRUPT_DISABLE;
974 pci_conf_write(pc, 0, PCI_COMMAND_STATUS_REG, cmdsts);
975
976 #if 0
977 /*
978 *
979 */
980 pq3pci_intr_source_lookup(sc, PIH_MAKE(0, IST_LEVEL, 0));
981 #endif
982 #if 0
983 if (sc->sc_pcie)
984 pci_conf_print(pc, 0, NULL);
985 #endif
986
987 config_found_ia(self, "pcibus", &pba, pcibusprint);
988 }
989
990 static void
991 pq3pci_attach_hook(device_t parent, device_t self,
992 struct pcibus_attach_args *pba)
993 {
994 /* do nothing */
995 }
996
997 static int
998 pq3pci_bus_maxdevs(void *v, int busno)
999 {
1000 struct pq3pci_softc * const sc = v;
1001 return sc->sc_pcie && busno < 2 ? 1 : 32;
1002 }
1003
1004 static void
1005 pq3pci_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func)
1006 {
1007 if (bus)
1008 *bus = (tag >> 16) & 0xff;
1009 if (dev)
1010 *dev = (tag >> 11) & 0x1f;
1011 if (func)
1012 *func = (tag >> 8) & 0x07;
1013 }
1014
1015 static pcitag_t
1016 pq3pci_make_tag(void *v, int bus, int dev, int func)
1017 {
1018 return (bus << 16) | (dev << 11) | (func << 8);
1019 }
1020
1021 #if 0
1022 static inline pcitag_t
1023 pq3pci_config_addr_read(pci_chipset_tag_t pc)
1024 {
1025 pcitag_t v;
1026 __asm volatile("lwz\t%0, 0(%1)" : "=r"(v) : "b"(pc->pc_addr));
1027 __asm volatile("mbar\n\tmsync");
1028 return v;
1029 }
1030 #endif
1031
1032 static inline void
1033 pq3pci_config_addr_write(pci_chipset_tag_t pc, pcitag_t v)
1034 {
1035 __asm volatile("stw\t%0, 0(%1)" :: "r"(v), "b"(pc->pc_addr));
1036 __asm volatile("mbar\n\tmsync");
1037 }
1038
1039 static inline pcireg_t
1040 pq3pci_config_data_read(pci_chipset_tag_t pc)
1041 {
1042 pcireg_t v;
1043 __asm volatile("lwbrx\t%0, 0, %1" : "=r"(v) : "b"(pc->pc_data));
1044 __asm volatile("mbar\n\tmsync");
1045 return v;
1046 }
1047
1048 static inline void
1049 pq3pci_config_data_write(pci_chipset_tag_t pc, pcireg_t v)
1050 {
1051 __asm volatile("stwbrx\t%0, 0, %1" :: "r"(v), "r"(pc->pc_data));
1052 __asm volatile("mbar\n\tmsync");
1053 }
1054
1055 static pcireg_t
1056 pq3pci_conf_read(void *v, pcitag_t tag, int reg)
1057 {
1058 struct pq3pci_softc * const sc = v;
1059 struct genppc_pci_chipset * const pc = &sc->sc_pc;
1060
1061 if (reg >= 256) {
1062 if (!sc->sc_pcie)
1063 return 0xffffffff;
1064 reg = (reg & 0xff) | ((reg & 0xf00) << 16);
1065 }
1066 if (sc->sc_pcie && ((tag >> 16) & 0xff) != 0) {
1067 // pcireg_t slot_status = pci_conf_read(pc, 0, 0x64);
1068 // printf("%s: tag 0x0 slot status: %#x\n",__func__, slot_status);
1069 // if ((slot_status & __BIT(6+16)) == 0)
1070 // printf(" addr=%#llx ", tag | reg | PEX_CONFIG_ADDR_EN);
1071 // return 0xffffffff;
1072 }
1073
1074 mutex_spin_enter(sc->sc_conf_lock);
1075
1076 pq3pci_config_addr_write(pc, tag | reg | PEX_CONFIG_ADDR_EN);
1077 pcireg_t rv = pq3pci_config_data_read(pc);
1078
1079 mutex_spin_exit(sc->sc_conf_lock);
1080
1081 #if 0
1082 uint32_t err = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PEX_ERR_DR);
1083 if (err & PEXERRDR_ICCA) {
1084 aprint_error_dev(sc->sc_dev, "%s: tag %#x reg %#x icca: %#x\n",
1085 __func__, tag, reg, pq3pci_config_addr_read(pc));
1086 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEX_ERR_DR,
1087 PEXERRDR_ICCA);
1088 }
1089 #endif
1090 return rv;
1091 }
1092
1093 static void
1094 pq3pci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
1095 {
1096 struct pq3pci_softc * const sc = v;
1097 struct genppc_pci_chipset * const pc = &sc->sc_pc;
1098
1099 if (reg >= 256) {
1100 if (!sc->sc_pcie)
1101 return;
1102 reg = (reg & 0xff) | ((reg & 0xf00) << 16);
1103 }
1104
1105 mutex_spin_enter(sc->sc_conf_lock);
1106
1107 #if 0
1108 aprint_error_dev(sc->sc_dev, "%s: tag %#x reg %#x data %#x\n",
1109 __func__, tag, reg, data);
1110 #endif
1111 pq3pci_config_addr_write(pc, tag | reg | PEX_CONFIG_ADDR_EN);
1112 pq3pci_config_data_write(pc, data);
1113
1114 mutex_spin_exit(sc->sc_conf_lock);
1115 }
1116
1117 static int
1118 pq3pci_conf_hook(void *v, int bus, int dev, int func, pcireg_t id)
1119 {
1120 struct pq3pci_softc * const sc = v;
1121 if (sc->sc_pcie && bus != 0) {
1122 pcireg_t slot_status = pci_conf_read(&sc->sc_pc, 0, 0x64);
1123 if ((slot_status & __BIT(6+16)) == 0)
1124 return 0;
1125 }
1126 if (!sc->sc_pcie && bus == 0 && dev == 0) {
1127 return PCI_CONF_DEFAULT ^ (PCI_CONF_MAP_IO|PCI_CONF_MAP_MEM|PCI_CONF_MAP_ROM);
1128 }
1129 return PCI_CONF_DEFAULT;
1130 }
1131
1132 static void
1133 pq3pci_msi_group_setup(struct pq3pci_msigroup *msig, u_int group, int ipl)
1134 {
1135 const char (*intr_names)[8] = msi_intr_names[group];
1136
1137 KASSERT(ipl == IPL_VM);
1138
1139 pq3pci_msigroups[group] = msig;
1140 msig->msig_group = group;
1141 msig->msig_free_mask = ~0 << (group == 0);
1142 msig->msig_ipl = ipl;
1143 msig->msig_lock = mutex_obj_alloc(MUTEX_DEFAULT, ipl);
1144 msig->msig_ih = intr_establish(msig->msig_group, ipl, IST_MSIGROUP,
1145 pq3pci_msi_intr, msig);
1146 msig->msig_msir = OPENPIC_BASE + OPENPIC_MSIR(msig->msig_group);
1147 for (u_int i = 0; i < __arraycount(msig->msig_ihands); i++) {
1148 struct pq3pci_msihand * const msih = msig->msig_ihands + i;
1149 msih->msih_ih.ih_class = IH_MSI;
1150 msih->msih_ih.ih_func = pq3pci_msi_spurious_intr;
1151 msih->msih_ih.ih_arg = msih;
1152 msih->msih_group = msig;
1153 evcnt_attach_dynamic(&msih->msih_ev, EVCNT_TYPE_INTR,
1154 NULL, intr_names[i], "intr");
1155 evcnt_attach_dynamic(&msih->msih_ev_spurious, EVCNT_TYPE_INTR,
1156 &msih->msih_ev, intr_names[i], "spurious intr");
1157 }
1158 }
1159
1160 static pci_intr_handle_t
1161 pq3pci_msi_alloc(int ipl, u_int rmsi)
1162 {
1163 size_t freegroup = 0;
1164 size_t maplen = __arraycount(pq3pci_msigroups);
1165 KASSERT(rmsi <= 5);
1166 uint32_t bitmap[maplen];
1167
1168 for (u_int i = 0; i < maplen; i++) {
1169 struct pq3pci_msigroup * const msig = pq3pci_msigroups[i];
1170 if (msig == NULL) {
1171 bitmap[i] = 0;
1172 if (freegroup == 0)
1173 freegroup = i + 1;
1174 continue;
1175 }
1176 /*
1177 * If this msigroup has the wrong IPL or there's nothing
1178 * free, try the next one.
1179 */
1180 if (msig->msig_ipl != ipl || msig->msig_free_mask == 0) {
1181 bitmap[i] = 0;
1182 continue;
1183 }
1184
1185 bitmap[i] = msig->msig_free_mask;
1186 }
1187 for (u_int i = 0; i < maplen; i++) {
1188 uint32_t mapbits = bitmap[i];
1189 u_int n = ffs(mapbits);
1190 if (n--) {
1191 return PIH_MAKE(i * 32 + n, IST_MSI, 0);
1192 }
1193 }
1194
1195 if (freegroup-- == 0)
1196 return 0;
1197
1198 struct pq3pci_msigroup * const msig =
1199 kmem_zalloc(sizeof(*msig), KM_SLEEP);
1200 KASSERT(msig != NULL);
1201 pq3pci_msi_group_setup(msig, freegroup, ipl);
1202 u_int n = ffs(msig->msig_free_mask) - 1;
1203 return PIH_MAKE(freegroup * 32 + n, IST_MSI, 0);
1204 }
1205
1206 static struct pq3pci_msihand *
1207 pq3pci_msi_lookup(pci_intr_handle_t handle)
1208 {
1209 const int irq = PIH_IRQ(handle);
1210 KASSERT(irq < 256);
1211 struct pq3pci_msigroup * const msig = pq3pci_msigroups[irq / 32];
1212 KASSERT(msig != NULL);
1213 return &msig->msig_ihands[irq & 31];
1214 }
1215
1216 static struct pq3pci_msihand *
1217 pq3pci_msi_claim(pci_intr_handle_t handle)
1218 {
1219 const int irq = PIH_IRQ(handle);
1220 uint32_t irq_mask = __BIT(irq & 31);
1221 KASSERT(irq < 256);
1222 struct pq3pci_msigroup * const msig = pq3pci_msigroups[irq / 32];
1223 KASSERT(msig != NULL);
1224 struct pq3pci_msihand * const msih = &msig->msig_ihands[irq & 31];
1225 mutex_spin_enter(msig->msig_lock);
1226 KASSERT(msig->msig_free_mask & irq_mask);
1227 msig->msig_free_mask ^= irq_mask;
1228 mutex_spin_exit(msig->msig_lock);
1229 return msih;
1230 }
1231
1232 static struct pq3pci_intrsource *
1233 pq3pci_intr_source_lookup(struct pq3pci_softc *sc, pci_intr_handle_t handle)
1234 {
1235 struct pq3pci_intrsource *pis;
1236 SIMPLEQ_FOREACH(pis, &pq3pci_intrsources, pis_link) {
1237 if (pis->pis_handle == handle)
1238 return pis;
1239 }
1240 pis = kmem_zalloc(sizeof(*pis), KM_SLEEP);
1241 pq3pci_intr_source_setup(sc, pis, handle);
1242 return pis;
1243 }
1244
1245 static pci_intr_handle_t
1246 pq3pci_intr_handle_lookup(struct pq3pci_softc *sc,
1247 const struct pci_attach_args *pa)
1248 {
1249 prop_dictionary_t entry;
1250
1251 if (sc->sc_pcie) do {
1252 pcireg_t msictl;
1253 int msioff;
1254 if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_MSI,
1255 &msioff, &msictl))
1256 break;
1257 msictl = pci_conf_read(pa->pa_pc, pa->pa_tag, msioff);
1258 msictl &= ~PCI_MSI_CTL_MSI_ENABLE;
1259 msictl &= ~PCI_MSI_CTL_MME_MASK;
1260 int rmsi = __SHIFTOUT(msictl, PCI_MSI_CTL_MMC_MASK);
1261 pci_conf_write(pa->pa_pc, pa->pa_tag, msioff, msictl);
1262 pci_intr_handle_t handle = pq3pci_msi_alloc(IPL_VM, rmsi);
1263 struct pq3pci_msihand * const msih = pq3pci_msi_lookup(handle);
1264 msih->msih_tag = pa->pa_tag;
1265 msih->msih_msioff = msioff;
1266 return handle;
1267 } while (false);
1268
1269
1270 if (sc->sc_intrmask == 0) {
1271 entry = prop_dictionary_get(sc->sc_intrmap, "000000");
1272 } else {
1273 char prop_name[8];
1274 u_int intrinc = __LOWEST_SET_BIT(sc->sc_intrmask);
1275 pcitag_t tag = (pa->pa_intrpin - PCI_INTERRUPT_PIN_A) * intrinc;
1276
1277 snprintf(prop_name, sizeof(prop_name), "%06x",
1278 tag & sc->sc_intrmask);
1279
1280 #if 0
1281 printf("%s: %#x %#x %u (%u) -> %#x & %#x -> %#x <%s>\n",
1282 __func__, pa->pa_tag, pa->pa_intrtag, pa->pa_intrpin, pa->pa_rawintrpin,
1283 tag, sc->sc_intrmask, tag & sc->sc_intrmask, prop_name);
1284 #endif
1285
1286 entry = prop_dictionary_get(sc->sc_intrmap, prop_name);
1287 }
1288 KASSERT(entry != NULL);
1289 KASSERT(prop_object_type(entry) == PROP_TYPE_DICTIONARY);
1290
1291 prop_number_t pn_irq = prop_dictionary_get(entry, "interrupt");
1292 KASSERT(pn_irq != NULL);
1293 KASSERT(prop_object_type(pn_irq) == PROP_TYPE_NUMBER);
1294 int irq = prop_number_unsigned_integer_value(pn_irq);
1295 prop_number_t pn_ist = prop_dictionary_get(entry, "type");
1296 KASSERT(pn_ist != NULL);
1297 KASSERT(prop_object_type(pn_ist) == PROP_TYPE_NUMBER);
1298 int ist = prop_number_unsigned_integer_value(pn_ist);
1299
1300 return PIH_MAKE(irq, ist, 0);
1301 }
1302
1303 static int
1304 pq3pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *handlep)
1305 {
1306 struct pq3pci_softc * const sc = pa->pa_pc->pc_intr_v;
1307
1308 if (pa->pa_intrpin == PCI_INTERRUPT_PIN_NONE)
1309 return ENOENT;
1310
1311 *handlep = pq3pci_intr_handle_lookup(sc, pa);
1312
1313 return 0;
1314 }
1315
1316 static const char *
1317 pq3pci_intr_string(void *v, pci_intr_handle_t handle, char *buf, size_t len)
1318 {
1319 if (PIH_IST(handle) == IST_MSI) {
1320 const char (*intr_names)[8] = msi_intr_names[0];
1321 strlcpy(buf, intr_names[PIH_IRQ(handle)], len);
1322 return buf;
1323 }
1324
1325 return intr_string(PIH_IRQ(handle), PIH_IST(handle), buf, len);
1326 }
1327
1328 static const struct evcnt *
1329 pq3pci_intr_evcnt(void *v, pci_intr_handle_t handle)
1330 {
1331 struct pq3pci_softc * const sc = v;
1332 struct pq3pci_intrsource * const pis =
1333 pq3pci_intr_source_lookup(sc, handle);
1334
1335 KASSERT(pis != NULL);
1336
1337 return &pis->pis_ev;
1338 }
1339
1340 static void *
1341 pq3pci_intr_establish(void *v, pci_intr_handle_t handle, int ipl,
1342 int (*func)(void *), void *arg)
1343 {
1344 struct pq3pci_softc * const sc = v;
1345
1346 if (0) {
1347 struct pq3pci_callhand * const pch =
1348 kmem_zalloc(sizeof(*pch), KM_SLEEP);
1349 KASSERT(pch);
1350 pch->pch_ih.ih_arg = arg;
1351 pch->pch_ih.ih_func = func;
1352 pch->pch_ih.ih_sc = sc;
1353 pch->pch_ipl = ipl;
1354
1355 callout_init(&pch->pch_callout, 0);
1356 callout_reset(&pch->pch_callout, 1, pq3pci_pch_callout, pch);
1357
1358 return pch;
1359 }
1360
1361 const int ist = PIH_IST(handle);
1362
1363 if (ist == IST_MSI) {
1364 pci_chipset_tag_t pc = &sc->sc_pc;
1365 struct pq3pci_msihand * const msih = pq3pci_msi_claim(handle);
1366 pcireg_t cmdsts, msictl;
1367
1368 if (msih == NULL)
1369 return NULL;
1370
1371 struct pq3pci_msigroup * const msig = msih->msih_group;
1372 const pcitag_t tag = msih->msih_tag;
1373
1374 mutex_spin_enter(msig->msig_lock);
1375 msih->msih_ih.ih_class = IH_MSI;
1376 msih->msih_ih.ih_arg = arg;
1377 msih->msih_ih.ih_func = func;
1378 msih->msih_ih.ih_sc = sc;
1379
1380 int off = msih->msih_msioff;
1381 msictl = pci_conf_read(pc, tag, off);
1382
1383 /*
1384 * The PCSRBAR has already been setup as a 1:1 BAR so we point
1385 * MSIs at the MSII register in the OpenPIC.
1386 */
1387 off += 4;
1388 pci_conf_write(pc, tag, off,
1389 sc->sc_bst->pbs_offset + OPENPIC_BASE + OPENPIC_MSIIR);
1390
1391 /*
1392 * Upper address is going to be 0.
1393 */
1394 if (msictl & PCI_MSI_CTL_64BIT_ADDR) {
1395 off += 4;
1396 pci_conf_write(pc, tag, off, 0);
1397 }
1398
1399 /*
1400 * Set the magic value. Since PCI writes this to the least
1401 * significant byte of AD[31:0], let's hope the bridge byte
1402 * swaps to so it's the most significant bytes or nothing is
1403 * going to happen.
1404 */
1405 off += 4;
1406 pci_conf_write(pc, tag, off, PIH_IRQ(handle));
1407
1408 /*
1409 * Should the driver do this? How would it know to do it?
1410 */
1411 if (msictl & PCI_MSI_CTL_PERVEC_MASK) {
1412 off += 4;
1413 pci_conf_write(pc, tag, off, 0);
1414 }
1415
1416 /*
1417 * Let's make sure he won't raise any INTx. Technically
1418 * setting MSI enable will prevent that as well but might
1419 * as well be as safe as possible.
1420 */
1421 cmdsts = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
1422 cmdsts |= PCI_COMMAND_INTERRUPT_DISABLE;
1423 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, cmdsts);
1424
1425 #if 1
1426 /*
1427 * Now we can enable the MSI
1428 */
1429 msictl |= PCI_MSI_CTL_MSI_ENABLE;
1430 pci_conf_write(pc, tag, msih->msih_msioff, msictl);
1431 #endif
1432
1433 mutex_spin_exit(msig->msig_lock);
1434
1435 #if 0
1436 struct pq3pci_callhand * const pch =
1437 kmem_zalloc(sizeof(*pch), KM_SLEEP);
1438 KASSERT(pch);
1439
1440 pch->pch_ih.ih_arg = msig;
1441 pch->pch_ih.ih_func = pq3pci_msi_intr;
1442 #if 1
1443 pch->pch_ih.ih_arg = arg;
1444 pch->pch_ih.ih_func = func;
1445 #endif
1446 pch->pch_ih.ih_sc = sc;
1447 pch->pch_ipl = ipl;
1448
1449 callout_init(&pch->pch_callout, 0);
1450 callout_reset(&pch->pch_callout, 1, pq3pci_pch_callout, pch);
1451
1452 #if 1
1453 return pch;
1454 #endif
1455 #endif
1456
1457 return msih;
1458 } else {
1459 struct pq3pci_intrsource * const pis =
1460 pq3pci_intr_source_lookup(sc, handle);
1461 KASSERT(pis != NULL);
1462
1463 struct pq3pci_intrhand * const pih =
1464 kmem_zalloc(sizeof(*pih), KM_SLEEP);
1465
1466 if (pih == NULL)
1467 return NULL;
1468
1469 pih->pih_ih.ih_class = IH_INTX;
1470 pih->pih_ih.ih_func = func;
1471 pih->pih_ih.ih_arg = arg;
1472 pih->pih_ih.ih_sc = sc;
1473 pih->pih_ipl = ipl;
1474 pih->pih_source = pis;
1475
1476 mutex_spin_enter(pis->pis_lock);
1477 SIMPLEQ_INSERT_TAIL(&pis->pis_ihands, pih, pih_link);
1478 mutex_spin_exit(pis->pis_lock);
1479
1480 return pih;
1481 }
1482 }
1483
1484 static void
1485 pq3pci_intr_disestablish(void *v, void *ih)
1486 {
1487 struct pq3pci_genihand * const gih = ih;
1488
1489 if (gih->ih_class == IH_INTX) {
1490 struct pq3pci_intrhand * const pih = ih;
1491 struct pq3pci_intrsource * const pis = pih->pih_source;
1492
1493 mutex_spin_enter(pis->pis_lock);
1494 SIMPLEQ_REMOVE(&pis->pis_ihands, pih, pq3pci_intrhand, pih_link);
1495 mutex_spin_exit(pis->pis_lock);
1496
1497 kmem_free(pih, sizeof(*pih));
1498 return;
1499 }
1500 struct pq3pci_msihand * const msih = ih;
1501 struct pq3pci_msigroup * const msig = msih->msih_group;
1502 struct genppc_pci_chipset * const pc = &msih->msih_ih.ih_sc->sc_pc;
1503 const pcitag_t tag = msih->msih_tag;
1504
1505 mutex_spin_enter(msig->msig_lock);
1506
1507 /*
1508 * disable the MSI
1509 */
1510 pcireg_t msictl = pci_conf_read(pc, tag, msih->msih_msioff);
1511 msictl &= ~PCI_MSI_CTL_MSI_ENABLE;
1512 pci_conf_write(pc, tag, msih->msih_msioff, msictl);
1513
1514 msih->msih_ih.ih_func = pq3pci_msi_spurious_intr;
1515 msih->msih_ih.ih_arg = msig;
1516 msih->msih_ih.ih_sc = NULL;
1517 msih->msih_tag = 0;
1518 msih->msih_msioff = 0;
1519 mutex_spin_exit(msig->msig_lock);
1520 }
1521
1522 static void
1523 pq3pci_conf_interrupt(void *v, int bus, int dev, int pin, int swiz, int *iline)
1524 {
1525 }
1526
1527 static pci_chipset_tag_t
1528 pq3pci_pci_chipset_init(struct pq3pci_softc *sc)
1529 {
1530 struct genppc_pci_chipset * const pc = &sc->sc_pc;
1531
1532 pc->pc_conf_v = sc;
1533 pc->pc_attach_hook = pq3pci_attach_hook;
1534 pc->pc_bus_maxdevs = pq3pci_bus_maxdevs;
1535 pc->pc_make_tag = pq3pci_make_tag;
1536 pc->pc_conf_read = pq3pci_conf_read;
1537 pc->pc_conf_write = pq3pci_conf_write;
1538 #ifdef PCI_NETBSD_CONFIGURE
1539 pc->pc_conf_hook = pq3pci_conf_hook;
1540 #endif
1541
1542 pc->pc_intr_v = sc;
1543 pc->pc_intr_map = pq3pci_intr_map;
1544 pc->pc_intr_string = pq3pci_intr_string;
1545 pc->pc_intr_evcnt = pq3pci_intr_evcnt;
1546 pc->pc_intr_establish = pq3pci_intr_establish;
1547 pc->pc_intr_disestablish = pq3pci_intr_disestablish;
1548 pc->pc_conf_interrupt = pq3pci_conf_interrupt;
1549
1550 pc->pc_msi_v = sc;
1551 genppc_pci_chipset_msi_init(pc);
1552 #if 0
1553 pc->pc_msi_request = pq3pci_msi_request;
1554 pc->pc_msi_available = pq3pci_msi_available;
1555 pc->pc_msi_type = pq3pci_msi_type;
1556 pc->pc_msi_string = pq3pci_msi_string;
1557 pc->pc_msi_evcnt = genppc_pci_msi_evcnt;
1558 pc->pc_msi_establish = pq3pci_msi_establish;
1559 pc->pc_msix_establish = pq3pci_msix_establish;
1560 pc->pc_msi_disestablish = pq3pci_msi_disestablish;
1561 pc->pc_msi_release = pq3pci_msi_release;
1562 pc->pc_msi_free = pq3pci_msi_free;
1563 #endif
1564
1565 pc->pc_decompose_tag = pq3pci_decompose_tag;
1566 pc->pc_conf_hook = pq3pci_conf_hook;
1567
1568 /*
1569 * This is a horrible kludge but it makes life easier.
1570 */
1571 pc->pc_addr = (void *)(sc->sc_bsh + PEX_CONFIG_ADDR);
1572 pc->pc_data = (void *)(sc->sc_bsh + PEX_CONFIG_DATA);
1573 pc->pc_bus = 0;
1574 pc->pc_memt = &sc->sc_pci_mem_bst.bs_tag;
1575 pc->pc_iot = &sc->sc_pci_io_bst.bs_tag;
1576
1577 SIMPLEQ_INIT(&pc->pc_pbi);
1578
1579 return pc;
1580 }
1581