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