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