pq3pci.c revision 1.29 1 /* $NetBSD: pq3pci.c,v 1.29 2021/08/07 16:19:02 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.29 2021/08/07 16:19:02 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
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
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
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
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
568 pq3pci_msi_spurious_intr(void *v)
569 {
570 (void) v;
571
572 return 0;
573 }
574
575 static int
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
640 pq3pci_onchip_intr(void *v)
641 {
642 panic(__func__);
643 }
644
645 static int
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
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
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_integer_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
727 pq3pci_once_init(void)
728 {
729
730 mutex_init(&pq3pci_intrsources_lock, MUTEX_DEFAULT, IPL_VM);
731 mutex_init(&pq3pci_msigroups_lock, MUTEX_DEFAULT, IPL_VM);
732
733 return 0;
734 }
735
736 void
737 pq3pci_cpunode_attach(device_t parent, device_t self, void *aux)
738 {
739 struct cpunode_softc * const psc = device_private(parent);
740 struct pq3pci_softc * const sc = device_private(self);
741 struct cpunode_attach_args * const cna = aux;
742 struct cpunode_locators * const cnl = &cna->cna_locs;
743 char buf[32];
744
745 sc->sc_dev = self;
746 sc->sc_bst = cna->cna_memt;
747 psc->sc_children |= cna->cna_childmask;
748 sc->sc_pcie = strcmp(cnl->cnl_name, "pcie") == 0;
749
750 RUN_ONCE(&pq3pci_init_once, pq3pci_once_init);
751
752 const uint32_t pordevsr = cpu_read_4(GLOBAL_BASE + PORDEVSR);
753 if (sc->sc_pcie) {
754 u_int lanes = e500_truth_decode(cnl->cnl_instance, pordevsr,
755 pq3pci_pcie_lanes, __arraycount(pq3pci_pcie_lanes), 0);
756 if (lanes == 0) {
757 aprint_normal(": disabled\n");
758 return;
759 }
760 snprintf(buf, sizeof(buf), "PCI-Express x%u", lanes);
761 } else {
762 bool pcix_p = e500_truth_decode(cnl->cnl_instance, pordevsr,
763 pq3pci_pci_pcix, __arraycount(pq3pci_pci_pcix), 0);
764 u_int width = e500_truth_decode(cnl->cnl_instance, pordevsr,
765 pq3pci_pci_pci32, __arraycount(pq3pci_pci_pci32), 32);
766 snprintf(buf, sizeof(buf), "%u-bit PCI%s",
767 width, (pcix_p ? "X" : ""));
768 }
769
770 if (!pq3pci_intrmap_setup(sc, cnl))
771 return;
772
773 evcnt_attach_dynamic(&sc->sc_ev_spurious, EVCNT_TYPE_INTR, NULL,
774 device_xname(self), "spurious intr");
775
776 int error = bus_space_map(sc->sc_bst, cnl->cnl_addr, cnl->cnl_size, 0,
777 &sc->sc_bsh);
778 if (error) {
779 aprint_error(": failed to map registers: %d\n", error);
780 return;
781 }
782
783 u_int valid_owins = 0;
784 for (u_int i = 1, off = PEXOTAR1 - PEXOTAR0;
785 i < 4; i++, off += PEXOTAR1 - PEXOTAR0) {
786 struct pq3pci_owin owin;
787 owin.potar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
788 PEXOTAR0 + off);
789 owin.potear = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
790 PEXOTEAR0 + off);
791 owin.powbar = 0;
792 if (i > 0) {
793 /* Doesn't exist for outbound window 0 */
794 owin.powbar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
795 PEXOWBAR1 - (PEXOTAR1 - PEXOTAR0) + off);
796 }
797 owin.powar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
798 PEXOWAR0 + off);
799 #if 0
800 aprint_normal_dev(self,
801 "owin[%u]: potar=%#x potear=%#x powbar=%#x powar=%#x\n",
802 i, owin.potar, owin.potear, owin.powbar, owin.powar);
803 #endif
804 if (owin.powar & PEXOWAR_EN) {
805 valid_owins++;
806 pq3pci_owin_record(sc, i, &owin);
807 }
808 }
809 if (!pq3pci_owin_init(sc, &sc->sc_pci_io_bst, true)
810 || !pq3pci_owin_init(sc, &sc->sc_pci_mem_bst, false)) {
811 return;
812 }
813 #ifndef PCI_NETBSD_CONFIGURE
814 if (valid_owins == 0) {
815 aprint_normal(": %s controller%s\n", buf,
816 " (disabled)");
817 return;
818 }
819 #endif
820
821 u_int valid_iwins = 0;
822 for (u_int i = 0, off = 0; i < 3; i++, off += PEXITAR2 - PEXITAR1) {
823 struct pq3pci_iwin iwin;
824 iwin.pitar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
825 PEXITAR1 + off);
826 iwin.piwbar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
827 PEXIWBAR1 + off);
828 if (i > 0) {
829 /* Doesn't exist */
830 iwin.piwbear = bus_space_read_4(sc->sc_bst,
831 sc->sc_bsh,
832 PEXIWBEAR2 - (PEXITAR2 - PEXITAR1) + off);
833 } else {
834 iwin.piwbear = 0;
835 }
836 iwin.piwar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
837 PEXIWAR1 + off);
838 #if 0
839 aprint_normal_dev(self,
840 "iwin[%u]: pitar=%#x piwbar=%#x piwbear=%#x piwar=%#x\n",
841 i, iwin.pitar, iwin.piwbar, iwin.piwbear, iwin.piwar);
842 #endif
843 if (iwin.piwar & PEXIWAR_EN) {
844 valid_iwins++;
845 if (!pq3pci_iwin_setup(sc, i, &iwin))
846 return;
847 }
848 }
849
850 sc->sc_conf_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_VM);
851
852 pci_chipset_tag_t pc = pq3pci_pci_chipset_init(sc);
853
854 #ifndef PCI_NETBSD_CONFIGURE
855 if (valid_iwins == 0) {
856 aprint_normal(": %s controller%s\n", buf,
857 " (disabled)");
858 return;
859 }
860 #else
861 if (sc->sc_pcie && pci_conf_read(pc, 0, PEX_LTSSM) < LTSSM_L0) {
862 aprint_normal(": %s controller%s\n", buf,
863 " (offline)");
864 return;
865 }
866 if (!sc->sc_pcie && (pci_conf_read(pc, 0, PCI_PBFR) & PBFR_PAH)) {
867 aprint_normal(": %s controller%s\n", buf,
868 " (agent mode)");
869 return;
870 }
871 if (valid_iwins == 0) {
872 struct pq3pci_iwin iwin = {
873 .pitar = 0,
874 .piwbar = 0,
875 .piwbear = 0,
876 .piwar = PEXIWAR_EN|PEXIWAR_PF|PEXIWAR_TRGT_LOCALMEM
877 |PEXIWAR_RTT_MEM_SNOOP|PEXIWAR_WTT_MEM_SNOOP
878 |__SHIFTIN(30-__builtin_clz(pmemsize),PEXIWAR_IWS),
879 };
880 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXITAR2, iwin.pitar);
881 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWBAR2, iwin.piwbar);
882 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWBEAR2, iwin.piwbear);
883 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWAR2, iwin.piwar);
884
885 if (!pq3pci_iwin_setup(sc, 2, &iwin)) {
886 aprint_error(": error creating inbound window\n");
887 return;
888 }
889
890 }
891
892 if (valid_owins == 0) {
893 u_long membase, iobase;
894 error = extent_alloc(pcimem_ex, PCI_MEMSIZE, PCI_MEMSIZE,
895 PCI_MEMSIZE, EX_WAITOK, &membase);
896 if (error) {
897 aprint_error(
898 ": error allocating address space for %s: %d\n",
899 "PCI memory", error);
900 return;
901 }
902 struct pq3pci_owin owin1 = {
903 .potar = membase >> 12,
904 .potear = 0,
905 .powbar = membase >> 12,
906 .powar = PEXOWAR_EN|PEXOWAR_TC0
907 |PEXOWAR_RTT_MEM|PEXOWAR_WTT_MEM
908 |__SHIFTIN(ilog2(PCI_MEMSIZE)-1,PEXOWAR_OWS),
909 };
910 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTAR1, owin1.potar);
911 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTEAR1, owin1.potear);
912 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWBAR1, owin1.powbar);
913 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWAR1, owin1.powar);
914 pq3pci_owin_record(sc, 1, &owin1);
915 if (!pq3pci_owin_init(sc, &sc->sc_pci_mem_bst, false)) {
916 return;
917 }
918
919 error = extent_alloc(pciio_ex, PCI_IOSIZE, PCI_IOSIZE,
920 PCI_IOSIZE, EX_WAITOK, &iobase);
921 if (error) {
922 aprint_error(
923 ": error allocating address space for %s: %d\n",
924 "PCI I/O space", error);
925 return;
926 }
927 struct pq3pci_owin owin2 = {
928 .potar = 0,
929 .potear = 0,
930 .powbar = iobase >> 12,
931 .powar = PEXOWAR_EN|PEXOWAR_TC0
932 |PEXOWAR_RTT_IO|PEXOWAR_WTT_IO
933 |__SHIFTIN(ilog2(PCI_IOSIZE)-1,PEXOWAR_OWS),
934 };
935 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTAR2, owin2.potar);
936 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTEAR2, owin2.potear);
937 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWBAR2, owin2.powbar);
938 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWAR2, owin2.powar);
939 pq3pci_owin_record(sc, 2, &owin1);
940 if (!pq3pci_owin_init(sc, &sc->sc_pci_io_bst, true)) {
941 return;
942 }
943
944 struct pciconf_resources *pcires = pciconf_resource_init();
945
946 pciconf_resource_add(pcires, PCICONF_RESOURCE_IO,
947 0, PCI_IOSIZE);
948 pciconf_resource_add(pcires, PCICONF_RESOURCE_MEM,
949 membase, PCI_MEMSIZE);
950
951 error = pci_configure_bus(pc, pcires, 0,
952 curcpu()->ci_ci.dcache_line_size);
953
954 pciconf_resource_fini(pcires);
955
956 if (error) {
957 aprint_normal(": configuration failed\n");
958 return;
959 }
960 }
961 #endif
962
963 aprint_normal(": %s controller%s\n", buf, "");
964
965 struct pcibus_attach_args pba;
966 memset(&pba, 0, sizeof(pba));
967
968 pba.pba_flags = sc->sc_pba_flags | PCI_FLAGS_MSI_OKAY
969 | PCI_FLAGS_MSIX_OKAY;
970 if (pba.pba_flags & PCI_FLAGS_IO_OKAY)
971 pba.pba_iot = pc->pc_iot;
972 if (pba.pba_flags & PCI_FLAGS_MEM_OKAY)
973 pba.pba_memt = pc->pc_memt;
974 pba.pba_dmat = cna->cna_dmat;
975 pba.pba_pc = pc;
976 pba.pba_bus = 0;
977
978 /*
979 * Program BAR0 so that MSIs can work.
980 */
981 pci_conf_write(pc, 0, PCI_BAR0, sc->sc_bst->pbs_offset);
982 pcireg_t cmdsts = pci_conf_read(pc, 0, PCI_COMMAND_STATUS_REG);
983 cmdsts |= PCI_COMMAND_INTERRUPT_DISABLE;
984 pci_conf_write(pc, 0, PCI_COMMAND_STATUS_REG, cmdsts);
985
986 #if 0
987 /*
988 *
989 */
990 pq3pci_intr_source_lookup(sc, PIH_MAKE(0, IST_LEVEL, 0));
991 #endif
992 #if 0
993 if (sc->sc_pcie)
994 pci_conf_print(pc, 0, NULL);
995 #endif
996
997 config_found(self, &pba, pcibusprint, CFARGS_NONE);
998 }
999
1000 static void
1001 pq3pci_attach_hook(device_t parent, device_t self,
1002 struct pcibus_attach_args *pba)
1003 {
1004 /* do nothing */
1005 }
1006
1007 static int
1008 pq3pci_bus_maxdevs(void *v, int busno)
1009 {
1010 struct pq3pci_softc * const sc = v;
1011 return sc->sc_pcie && busno < 2 ? 1 : 32;
1012 }
1013
1014 static void
1015 pq3pci_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func)
1016 {
1017 if (bus)
1018 *bus = (tag >> 16) & 0xff;
1019 if (dev)
1020 *dev = (tag >> 11) & 0x1f;
1021 if (func)
1022 *func = (tag >> 8) & 0x07;
1023 }
1024
1025 static pcitag_t
1026 pq3pci_make_tag(void *v, int bus, int dev, int func)
1027 {
1028 return (bus << 16) | (dev << 11) | (func << 8);
1029 }
1030
1031 #if 0
1032 static inline pcitag_t
1033 pq3pci_config_addr_read(pci_chipset_tag_t pc)
1034 {
1035 pcitag_t v;
1036 __asm volatile("lwz\t%0, 0(%1)" : "=r"(v) : "b"(pc->pc_addr));
1037 __asm volatile("mbar\n\tmsync");
1038 return v;
1039 }
1040 #endif
1041
1042 static inline void
1043 pq3pci_config_addr_write(pci_chipset_tag_t pc, pcitag_t v)
1044 {
1045 __asm volatile("stw\t%0, 0(%1)" :: "r"(v), "b"(pc->pc_addr));
1046 __asm volatile("mbar\n\tmsync");
1047 }
1048
1049 static inline pcireg_t
1050 pq3pci_config_data_read(pci_chipset_tag_t pc)
1051 {
1052 pcireg_t v;
1053 __asm volatile("lwbrx\t%0, 0, %1" : "=r"(v) : "b"(pc->pc_data));
1054 __asm volatile("mbar\n\tmsync");
1055 return v;
1056 }
1057
1058 static inline void
1059 pq3pci_config_data_write(pci_chipset_tag_t pc, pcireg_t v)
1060 {
1061 __asm volatile("stwbrx\t%0, 0, %1" :: "r"(v), "r"(pc->pc_data));
1062 __asm volatile("mbar\n\tmsync");
1063 }
1064
1065 static pcireg_t
1066 pq3pci_conf_read(void *v, pcitag_t tag, int reg)
1067 {
1068 struct pq3pci_softc * const sc = v;
1069 struct genppc_pci_chipset * const pc = &sc->sc_pc;
1070
1071 if (reg < 0)
1072 return 0xffffffff;
1073 if (reg >= PCI_CONF_SIZE) {
1074 if (!sc->sc_pcie || reg >= PCI_EXTCONF_SIZE)
1075 return 0xffffffff;
1076 reg = (reg & 0xff) | ((reg & 0xf00) << 16);
1077 }
1078 if (sc->sc_pcie && ((tag >> 16) & 0xff) != 0) {
1079 // pcireg_t slot_status = pci_conf_read(pc, 0, 0x64);
1080 // printf("%s: tag 0x0 slot status: %#x\n",__func__, slot_status);
1081 // if ((slot_status & __BIT(6+16)) == 0)
1082 // printf(" addr=%#llx ", tag | reg | PEX_CONFIG_ADDR_EN);
1083 // return 0xffffffff;
1084 }
1085
1086 mutex_spin_enter(sc->sc_conf_lock);
1087
1088 pq3pci_config_addr_write(pc, tag | reg | PEX_CONFIG_ADDR_EN);
1089 pcireg_t rv = pq3pci_config_data_read(pc);
1090
1091 mutex_spin_exit(sc->sc_conf_lock);
1092
1093 #if 0
1094 uint32_t err = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PEX_ERR_DR);
1095 if (err & PEXERRDR_ICCA) {
1096 aprint_error_dev(sc->sc_dev, "%s: tag %#x reg %#x icca: %#x\n",
1097 __func__, tag, reg, pq3pci_config_addr_read(pc));
1098 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEX_ERR_DR,
1099 PEXERRDR_ICCA);
1100 }
1101 #endif
1102 return rv;
1103 }
1104
1105 static void
1106 pq3pci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
1107 {
1108 struct pq3pci_softc * const sc = v;
1109 struct genppc_pci_chipset * const pc = &sc->sc_pc;
1110
1111 if (reg < 0)
1112 return;
1113 if (reg >= PCI_CONF_SIZE) {
1114 if (!sc->sc_pcie || reg >= PCI_EXTCONF_SIZE)
1115 return;
1116 reg = (reg & 0xff) | ((reg & 0xf00) << 16);
1117 }
1118
1119 mutex_spin_enter(sc->sc_conf_lock);
1120
1121 #if 0
1122 aprint_error_dev(sc->sc_dev, "%s: tag %#x reg %#x data %#x\n",
1123 __func__, tag, reg, data);
1124 #endif
1125 pq3pci_config_addr_write(pc, tag | reg | PEX_CONFIG_ADDR_EN);
1126 pq3pci_config_data_write(pc, data);
1127
1128 mutex_spin_exit(sc->sc_conf_lock);
1129 }
1130
1131 #ifdef PCI_NETBSD_CONFIGURE
1132 static int
1133 pq3pci_conf_hook(void *v, int bus, int dev, int func, pcireg_t id)
1134 {
1135 struct pq3pci_softc * const sc = v;
1136 if (sc->sc_pcie && bus != 0) {
1137 pcireg_t slot_status = pci_conf_read(&sc->sc_pc, 0, 0x64);
1138 if ((slot_status & __BIT(6+16)) == 0)
1139 return 0;
1140 }
1141 if (!sc->sc_pcie && bus == 0 && dev == 0) {
1142 return PCI_CONF_DEFAULT ^ (PCI_CONF_MAP_IO|PCI_CONF_MAP_MEM|PCI_CONF_MAP_ROM);
1143 }
1144 return PCI_CONF_DEFAULT;
1145 }
1146 #endif
1147
1148 static void
1149 pq3pci_msi_group_setup(struct pq3pci_msigroup *msig, u_int group, int ipl)
1150 {
1151 char buf[12];
1152 const char (*intr_names)[8] = msi_intr_names[group];
1153
1154 KASSERT(ipl == IPL_VM);
1155 KASSERT(mutex_owned(&pq3pci_msigroups_lock));
1156
1157 msig->msig_group = group;
1158 msig->msig_free_mask = ~0 << (group == 0);
1159 msig->msig_ipl = ipl;
1160 mutex_init(&msig->msig_lock, MUTEX_DEFAULT, ipl);
1161 snprintf(buf, sizeof(buf), "msi %d-%d", group * 32, group * 32 + 31);
1162 msig->msig_ih = intr_establish_xname(msig->msig_group, ipl,
1163 IST_MSIGROUP, pq3pci_msi_intr, msig, buf);
1164 msig->msig_msir = OPENPIC_BASE + OPENPIC_MSIR(msig->msig_group);
1165 for (u_int i = 0; i < __arraycount(msig->msig_ihands); i++) {
1166 struct pq3pci_msihand * const msih = msig->msig_ihands + i;
1167 msih->msih_ih.ih_class = IH_MSI;
1168 msih->msih_ih.ih_func = pq3pci_msi_spurious_intr;
1169 msih->msih_ih.ih_arg = msih;
1170 msih->msih_group = msig;
1171 evcnt_attach_dynamic(&msih->msih_ev, EVCNT_TYPE_INTR,
1172 NULL, intr_names[i], "intr");
1173 evcnt_attach_dynamic(&msih->msih_ev_spurious, EVCNT_TYPE_INTR,
1174 &msih->msih_ev, intr_names[i], "spurious intr");
1175 }
1176 pq3pci_msigroups[group] = msig;
1177 }
1178
1179 static struct pq3pci_msihand *
1180 pq3pci_msi_lookup(pci_intr_handle_t handle)
1181 {
1182 const int irq = PIH_IRQ(handle);
1183 KASSERT(irq < 256);
1184 struct pq3pci_msigroup * const msig = pq3pci_msigroups[irq / 32];
1185 KASSERT(msig != NULL);
1186 return &msig->msig_ihands[irq & 31];
1187 }
1188
1189 static struct pq3pci_msihand *
1190 pq3pci_msi_claim(pci_intr_handle_t handle)
1191 {
1192 const int irq = PIH_IRQ(handle);
1193 uint32_t irq_mask = __BIT(irq & 31);
1194 KASSERT(irq < 256);
1195 struct pq3pci_msigroup * const msig = pq3pci_msigroups[irq / 32];
1196 KASSERT(msig != NULL);
1197 struct pq3pci_msihand * const msih = &msig->msig_ihands[irq & 31];
1198 mutex_spin_enter(&msig->msig_lock);
1199 msig->msig_free_mask ^= irq_mask;
1200 mutex_spin_exit(&msig->msig_lock);
1201 return msih;
1202 }
1203
1204 static pci_intr_handle_t
1205 pq3pci_msi_alloc_one(int ipl)
1206 {
1207 size_t freegroup = 0;
1208 const size_t maplen = __arraycount(pq3pci_msigroups);
1209 uint32_t bitmap[maplen];
1210 pci_intr_handle_t handle;
1211
1212 mutex_spin_enter(&pq3pci_msigroups_lock);
1213 for (u_int i = 0; i < maplen; i++) {
1214 struct pq3pci_msigroup * const msig = pq3pci_msigroups[i];
1215 if (msig == NULL) {
1216 bitmap[i] = 0;
1217 if (freegroup == 0)
1218 freegroup = i + 1;
1219 continue;
1220 }
1221 /*
1222 * If this msigroup has the wrong IPL or there's nothing
1223 * free, try the next one.
1224 */
1225 if (msig->msig_ipl != ipl || msig->msig_free_mask == 0) {
1226 bitmap[i] = 0;
1227 continue;
1228 }
1229
1230 bitmap[i] = msig->msig_free_mask;
1231 }
1232 for (u_int i = 0; i < maplen; i++) {
1233 uint32_t mapbits = bitmap[i];
1234 u_int n = ffs(mapbits);
1235 if (n--) {
1236 handle = PIH_MAKE(i * 32 + n, IST_MSI, 0);
1237 struct pq3pci_msihand * const msih __diagused =
1238 pq3pci_msi_claim(handle);
1239 KASSERT(msih != NULL);
1240 mutex_spin_exit(&pq3pci_msigroups_lock);
1241 return handle;
1242 }
1243 }
1244
1245 if (freegroup-- == 0) {
1246 mutex_spin_exit(&pq3pci_msigroups_lock);
1247 return 0;
1248 }
1249
1250 struct pq3pci_msigroup * const msig =
1251 kmem_zalloc(sizeof(*msig), KM_NOSLEEP);
1252 if (msig == NULL) {
1253 mutex_spin_exit(&pq3pci_msigroups_lock);
1254 return 0;
1255 }
1256 pq3pci_msi_group_setup(msig, freegroup, ipl);
1257 u_int n = ffs(msig->msig_free_mask) - 1;
1258 handle = PIH_MAKE(freegroup * 32 + n, IST_MSI, 0);
1259 struct pq3pci_msihand * const msih __diagused =
1260 pq3pci_msi_claim(handle);
1261 KASSERT(msih != NULL);
1262 mutex_spin_exit(&pq3pci_msigroups_lock);
1263 return handle;
1264 }
1265
1266 static int
1267 pq3pci_msi_alloc_vectors(struct pq3pci_softc *sc,
1268 const struct pci_attach_args *pa, pci_intr_handle_t **ihps, int count)
1269 {
1270 pci_intr_handle_t *vectors;
1271 struct pq3pci_msihand * msih;
1272 pcireg_t msictl;
1273 int msioff;
1274
1275 *ihps = NULL;
1276
1277 if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_MSI, &msioff,
1278 NULL))
1279 return ENODEV;
1280
1281 msictl = pci_conf_read(pa->pa_pc, pa->pa_tag, msioff);
1282 msictl &= ~PCI_MSI_CTL_MSI_ENABLE;
1283 msictl &= ~PCI_MSI_CTL_MME_MASK;
1284 pci_conf_write(pa->pa_pc, pa->pa_tag, msioff, msictl);
1285
1286 const size_t alloc_size = sizeof(*vectors) * count;
1287 vectors = kmem_zalloc(alloc_size, KM_SLEEP);
1288
1289 for (int i = 0; i < count; ++i) {
1290 pci_intr_handle_t handle = pq3pci_msi_alloc_one(IPL_VM);
1291 if (handle == 0) {
1292 for (int j = i - 1; j >= 0; j--) {
1293 msih = pq3pci_msi_claim(vectors[j]);
1294 msih->msih_tag = 0;
1295 msih->msih_msioff = 0;
1296 }
1297 kmem_free(vectors, alloc_size);
1298 return EBUSY;
1299 }
1300 vectors[i] = handle;
1301
1302 msih = pq3pci_msi_lookup(handle);
1303 msih->msih_tag = pa->pa_tag;
1304 msih->msih_msioff = msioff;
1305 }
1306
1307 *ihps = vectors;
1308 return 0;
1309 }
1310
1311 static void
1312 pq3pci_msi_free_vectors(struct pq3pci_softc *sc, pci_intr_handle_t *ihp,
1313 int count)
1314 {
1315
1316 KASSERT(count > 0);
1317
1318 for (int i = 0; i < count; ++i) {
1319 struct pq3pci_msihand * const msih __diagused =
1320 pq3pci_msi_claim(ihp[i]);
1321 KASSERT(msih != NULL);
1322 }
1323 kmem_free(ihp, sizeof(*ihp) * count);
1324 }
1325
1326 static struct pq3pci_intrsource *
1327 pq3pci_intr_source_lookup(struct pq3pci_softc *sc, pci_intr_handle_t handle)
1328 {
1329 struct pq3pci_intrsource *pis;
1330 mutex_spin_enter(&pq3pci_intrsources_lock);
1331 SIMPLEQ_FOREACH(pis, &pq3pci_intrsources, pis_link) {
1332 if (pis->pis_handle == handle) {
1333 mutex_spin_exit(&pq3pci_intrsources_lock);
1334 return pis;
1335 }
1336 }
1337 pis = kmem_zalloc(sizeof(*pis), KM_NOSLEEP);
1338 if (pis != NULL)
1339 pq3pci_intr_source_setup(sc, pis, handle);
1340 mutex_spin_exit(&pq3pci_intrsources_lock);
1341 return pis;
1342 }
1343
1344 static pci_intr_handle_t
1345 pq3pci_intr_handle_lookup(struct pq3pci_softc *sc,
1346 const struct pci_attach_args *pa)
1347 {
1348 prop_dictionary_t entry;
1349
1350 #ifndef PQ3PCI_INTR_MAP_NO_USE_MSI
1351 if (sc->sc_pcie) do {
1352 pcireg_t msictl;
1353 int msioff;
1354 if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_MSI,
1355 &msioff, NULL))
1356 break;
1357 msictl = pci_conf_read(pa->pa_pc, pa->pa_tag, msioff);
1358 msictl &= ~PCI_MSI_CTL_MSI_ENABLE;
1359 msictl &= ~PCI_MSI_CTL_MME_MASK;
1360 pci_conf_write(pa->pa_pc, pa->pa_tag, msioff, msictl);
1361 pci_intr_handle_t handle = pq3pci_msi_alloc_one(IPL_VM);
1362 struct pq3pci_msihand * const msih = pq3pci_msi_lookup(handle);
1363 msih->msih_tag = pa->pa_tag;
1364 msih->msih_msioff = msioff;
1365 return handle;
1366 } while (false);
1367 #endif
1368
1369 if (sc->sc_intrmask == 0) {
1370 entry = prop_dictionary_get(sc->sc_intrmap, "000000");
1371 } else {
1372 char prop_name[8];
1373 u_int intrinc = __LOWEST_SET_BIT(sc->sc_intrmask);
1374 pcitag_t tag = (pa->pa_intrpin - PCI_INTERRUPT_PIN_A) * intrinc;
1375
1376 snprintf(prop_name, sizeof(prop_name), "%06x",
1377 tag & sc->sc_intrmask);
1378
1379 #if 0
1380 printf("%s: %#x %#x %u (%u) -> %#x & %#x -> %#x <%s>\n",
1381 __func__, pa->pa_tag, pa->pa_intrtag, pa->pa_intrpin, pa->pa_rawintrpin,
1382 tag, sc->sc_intrmask, tag & sc->sc_intrmask, prop_name);
1383 #endif
1384
1385 entry = prop_dictionary_get(sc->sc_intrmap, prop_name);
1386 }
1387 KASSERT(entry != NULL);
1388 KASSERT(prop_object_type(entry) == PROP_TYPE_DICTIONARY);
1389
1390 prop_number_t pn_irq = prop_dictionary_get(entry, "interrupt");
1391 KASSERT(pn_irq != NULL);
1392 KASSERT(prop_object_type(pn_irq) == PROP_TYPE_NUMBER);
1393 int irq = prop_number_unsigned_integer_value(pn_irq);
1394 prop_number_t pn_ist = prop_dictionary_get(entry, "type");
1395 KASSERT(pn_ist != NULL);
1396 KASSERT(prop_object_type(pn_ist) == PROP_TYPE_NUMBER);
1397 int ist = prop_number_unsigned_integer_value(pn_ist);
1398
1399 return PIH_MAKE(irq, ist, 0);
1400 }
1401
1402 static int
1403 pq3pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *handlep)
1404 {
1405 struct pq3pci_softc * const sc = pa->pa_pc->pc_intr_v;
1406
1407 if (pa->pa_intrpin == PCI_INTERRUPT_PIN_NONE)
1408 return ENOENT;
1409
1410 *handlep = pq3pci_intr_handle_lookup(sc, pa);
1411
1412 return 0;
1413 }
1414
1415 static const char *
1416 pq3pci_intr_string(void *v, pci_intr_handle_t handle, char *buf, size_t len)
1417 {
1418 if (PIH_IST(handle) == IST_MSI) {
1419 const char (*intr_names)[8] = msi_intr_names[0];
1420 strlcpy(buf, intr_names[PIH_IRQ(handle)], len);
1421 return buf;
1422 }
1423
1424 return intr_string(PIH_IRQ(handle), PIH_IST(handle), buf, len);
1425 }
1426
1427 static const struct evcnt *
1428 pq3pci_intr_evcnt(void *v, pci_intr_handle_t handle)
1429 {
1430 struct pq3pci_softc * const sc = v;
1431 if (PIH_IST(handle) == IST_MSI) {
1432 struct pq3pci_msihand * const msih = pq3pci_msi_lookup(handle);
1433
1434 KASSERT(msih != NULL);
1435
1436 return &msih->msih_ev;
1437 }
1438 struct pq3pci_intrsource * const pis =
1439 pq3pci_intr_source_lookup(sc, handle);
1440 if (pis != NULL)
1441 return &pis->pis_ev;
1442 return NULL;
1443 }
1444
1445 static void *
1446 pq3pci_intr_establish(void *v, pci_intr_handle_t handle, int ipl,
1447 int (*func)(void *), void *arg, const char *xname)
1448 {
1449 struct pq3pci_softc * const sc = v;
1450 const int ist = PIH_IST(handle);
1451
1452 if (ist == IST_MSI) {
1453 pci_chipset_tag_t pc = &sc->sc_pc;
1454 struct pq3pci_msihand * const msih = pq3pci_msi_lookup(handle);
1455 pcireg_t cmdsts, msictl;
1456
1457 if (msih == NULL)
1458 return NULL;
1459
1460 struct pq3pci_msigroup * const msig = msih->msih_group;
1461 const pcitag_t tag = msih->msih_tag;
1462
1463 mutex_spin_enter(&msig->msig_lock);
1464 msih->msih_ih.ih_class = IH_MSI;
1465 msih->msih_ih.ih_arg = arg;
1466 msih->msih_ih.ih_func = func;
1467 msih->msih_ih.ih_sc = sc;
1468
1469 int off = msih->msih_msioff;
1470 msictl = pci_conf_read(pc, tag, off);
1471
1472 /*
1473 * The PCSRBAR has already been setup as a 1:1 BAR so we point
1474 * MSIs at the MSII register in the OpenPIC.
1475 */
1476 off += 4;
1477 pci_conf_write(pc, tag, off,
1478 sc->sc_bst->pbs_offset + OPENPIC_BASE + OPENPIC_MSIIR);
1479
1480 /*
1481 * Upper address is going to be 0.
1482 */
1483 if (msictl & PCI_MSI_CTL_64BIT_ADDR) {
1484 off += 4;
1485 pci_conf_write(pc, tag, off, 0);
1486 }
1487
1488 /*
1489 * Set the magic value. Since PCI writes this to the least
1490 * significant byte of AD[31:0], let's hope the bridge byte
1491 * swaps to so it's the most significant bytes or nothing is
1492 * going to happen.
1493 */
1494 off += 4;
1495 pci_conf_write(pc, tag, off, PIH_IRQ(handle));
1496
1497 /*
1498 * Should the driver do this? How would it know to do it?
1499 */
1500 if (msictl & PCI_MSI_CTL_PERVEC_MASK) {
1501 off += 4;
1502 pci_conf_write(pc, tag, off, 0);
1503 }
1504
1505 /*
1506 * Let's make sure he won't raise any INTx. Technically
1507 * setting MSI enable will prevent that as well but might
1508 * as well be as safe as possible.
1509 */
1510 cmdsts = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
1511 cmdsts |= PCI_COMMAND_INTERRUPT_DISABLE;
1512 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, cmdsts);
1513
1514 #if 1
1515 /*
1516 * Now we can enable the MSI
1517 */
1518 msictl |= PCI_MSI_CTL_MSI_ENABLE;
1519 pci_conf_write(pc, tag, msih->msih_msioff, msictl);
1520 #endif
1521
1522 mutex_spin_exit(&msig->msig_lock);
1523
1524 return msih;
1525 }
1526
1527 struct pq3pci_intrsource * const pis =
1528 pq3pci_intr_source_lookup(sc, handle);
1529 if (pis == NULL)
1530 return NULL;
1531
1532 struct pq3pci_intrhand * const pih =
1533 kmem_zalloc(sizeof(*pih), KM_SLEEP);
1534 pih->pih_ih.ih_class = IH_INTX;
1535 pih->pih_ih.ih_func = func;
1536 pih->pih_ih.ih_arg = arg;
1537 pih->pih_ih.ih_sc = sc;
1538 pih->pih_ipl = ipl;
1539 pih->pih_source = pis;
1540
1541 mutex_spin_enter(&pis->pis_lock);
1542 SIMPLEQ_INSERT_TAIL(&pis->pis_ihands, pih, pih_link);
1543 mutex_spin_exit(&pis->pis_lock);
1544
1545 return pih;
1546 }
1547
1548 static void
1549 pq3pci_intr_disestablish(void *v, void *ih)
1550 {
1551 struct pq3pci_genihand * const gih = ih;
1552
1553 if (gih->ih_class == IH_INTX) {
1554 struct pq3pci_intrhand * const pih = ih;
1555 struct pq3pci_intrsource * const pis = pih->pih_source;
1556
1557 mutex_spin_enter(&pis->pis_lock);
1558 SIMPLEQ_REMOVE(&pis->pis_ihands, pih, pq3pci_intrhand, pih_link);
1559 mutex_spin_exit(&pis->pis_lock);
1560
1561 kmem_free(pih, sizeof(*pih));
1562 return;
1563 }
1564
1565 struct pq3pci_msihand * const msih = ih;
1566 struct pq3pci_msigroup * const msig = msih->msih_group;
1567 struct genppc_pci_chipset * const pc = &msih->msih_ih.ih_sc->sc_pc;
1568 const pcitag_t tag = msih->msih_tag;
1569
1570 mutex_spin_enter(&msig->msig_lock);
1571
1572 /*
1573 * disable the MSI
1574 */
1575 pcireg_t msictl = pci_conf_read(pc, tag, msih->msih_msioff);
1576 msictl &= ~PCI_MSI_CTL_MSI_ENABLE;
1577 pci_conf_write(pc, tag, msih->msih_msioff, msictl);
1578
1579 msih->msih_ih.ih_func = pq3pci_msi_spurious_intr;
1580 msih->msih_ih.ih_arg = msig;
1581 msih->msih_ih.ih_sc = NULL;
1582 msih->msih_tag = 0;
1583 msih->msih_msioff = 0;
1584 mutex_spin_exit(&msig->msig_lock);
1585 }
1586
1587 static pci_intr_type_t
1588 pq3pci_intr_type(void *v, pci_intr_handle_t handle)
1589 {
1590 const int ist = PIH_IST(handle);
1591
1592 if (ist == IST_MSI)
1593 return PCI_INTR_TYPE_MSI;
1594 return PCI_INTR_TYPE_INTX;
1595 }
1596
1597 static int
1598 pq3pci_intr_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps,
1599 int *counts, pci_intr_type_t max_type)
1600 {
1601 int cnt[PCI_INTR_TYPE_SIZE];
1602 int error;
1603
1604 memset(cnt, 0, sizeof(cnt));
1605 if (counts == NULL) {
1606 /* simple pattern */
1607 cnt[PCI_INTR_TYPE_INTX] = 1;
1608 cnt[PCI_INTR_TYPE_MSI] = 1;
1609 } else {
1610 switch (max_type) {
1611 case PCI_INTR_TYPE_MSIX:
1612 cnt[PCI_INTR_TYPE_MSIX] = counts[PCI_INTR_TYPE_MSIX];
1613 /*FALLTHROUGH*/
1614 case PCI_INTR_TYPE_MSI:
1615 cnt[PCI_INTR_TYPE_MSI] = counts[PCI_INTR_TYPE_MSI];
1616 /*FALLTHROUGH*/
1617 case PCI_INTR_TYPE_INTX:
1618 cnt[PCI_INTR_TYPE_INTX] = counts[PCI_INTR_TYPE_INTX];
1619 break;
1620 default:
1621 return EINVAL;
1622 }
1623 }
1624
1625 if (counts != NULL)
1626 memset(counts, 0, sizeof(counts[0]) * (max_type + 1));
1627 error = EINVAL;
1628
1629 /* try MSI-X */
1630 if (cnt[PCI_INTR_TYPE_MSIX] == -1) /* use hardware max */
1631 cnt[PCI_INTR_TYPE_MSIX] = pci_msix_count(pa->pa_pc, pa->pa_tag);
1632 if (cnt[PCI_INTR_TYPE_MSIX] > 0) {
1633 error = pci_msix_alloc_exact(pa, ihps, cnt[PCI_INTR_TYPE_MSIX]);
1634 if (error == 0) {
1635 KASSERTMSG(counts != NULL,
1636 "If MSI-X is used, counts must not be NULL.");
1637 counts[PCI_INTR_TYPE_MSIX] = cnt[PCI_INTR_TYPE_MSIX];
1638 goto out;
1639 }
1640 }
1641
1642 /* try MSI */
1643 if (cnt[PCI_INTR_TYPE_MSI] == -1) /* use hardware max */
1644 cnt[PCI_INTR_TYPE_MSI] = pci_msi_count(pa->pa_pc, pa->pa_tag);
1645 if (cnt[PCI_INTR_TYPE_MSI] > 0) {
1646 error = pci_msi_alloc_exact(pa, ihps, cnt[PCI_INTR_TYPE_MSI]);
1647 if (error == 0) {
1648 if (counts != NULL) {
1649 counts[PCI_INTR_TYPE_MSI] =
1650 cnt[PCI_INTR_TYPE_MSI];
1651 }
1652 goto out;
1653 }
1654 }
1655
1656 /* try INTx */
1657 if (cnt[PCI_INTR_TYPE_INTX] > 0) {
1658 error = pci_intx_alloc(pa, ihps);
1659 if (error == 0 && counts != NULL) {
1660 counts[PCI_INTR_TYPE_INTX] = 1;
1661 }
1662 }
1663
1664 out:
1665 return error;
1666 }
1667
1668 static void
1669 pq3pci_intr_release(void *v, pci_intr_handle_t *ihps, int count)
1670 {
1671
1672 if (ihps == NULL)
1673 return;
1674
1675 const int ist = PIH_IST(*ihps);
1676 if (ist == IST_MSI)
1677 pq3pci_msi_free_vectors(v, ihps, count);
1678 else
1679 genppc_pci_intr_release(v, ihps, count);
1680 }
1681
1682 static void
1683 pq3pci_conf_interrupt(void *v, int bus, int dev, int pin, int swiz, int *iline)
1684 {
1685 }
1686
1687 /* experimental MSI support */
1688
1689 /*
1690 * This function is used by device drivers like pci_intr_map().
1691 *
1692 * "ihps" is the array of vector numbers which MSI used instead of IRQ number.
1693 * "count" must be powr of 2.
1694 * "count" can decrease if sturct intrsource cannot be allocated.
1695 * if count == 0, return non-zero value.
1696 */
1697 static int
1698 pq3pci_msi_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps,
1699 int *count, bool exact)
1700 {
1701 struct pq3pci_softc * const sc = pa->pa_pc->pc_msi_v;
1702 int hw_max;
1703 int error;
1704
1705 if (*count < 1)
1706 return EINVAL;
1707 if (((*count - 1) & *count) != 0)
1708 return EINVAL;
1709
1710 hw_max = pci_msi_count(pa->pa_pc, pa->pa_tag);
1711 if (hw_max == 0)
1712 return ENODEV;
1713
1714 if (*count > hw_max)
1715 *count = hw_max;
1716
1717 *ihps = NULL;
1718 for (; *count > 0; (*count) >>= 1) {
1719 error = pq3pci_msi_alloc_vectors(sc, pa, ihps, *count);
1720 if (error == 0)
1721 break;
1722 if (exact)
1723 return error;
1724 }
1725 if (*ihps == NULL)
1726 return ENXIO;
1727
1728 return 0;
1729 }
1730
1731 static pci_chipset_tag_t
1732 pq3pci_pci_chipset_init(struct pq3pci_softc *sc)
1733 {
1734 struct genppc_pci_chipset * const pc = &sc->sc_pc;
1735
1736 pc->pc_conf_v = sc;
1737 pc->pc_attach_hook = pq3pci_attach_hook;
1738 pc->pc_bus_maxdevs = pq3pci_bus_maxdevs;
1739 pc->pc_make_tag = pq3pci_make_tag;
1740 pc->pc_conf_read = pq3pci_conf_read;
1741 pc->pc_conf_write = pq3pci_conf_write;
1742 #ifdef PCI_NETBSD_CONFIGURE
1743 pc->pc_conf_hook = pq3pci_conf_hook;
1744 #endif
1745
1746 pc->pc_intr_v = sc;
1747 pc->pc_intr_map = pq3pci_intr_map;
1748 pc->pc_intr_string = pq3pci_intr_string;
1749 pc->pc_intr_evcnt = pq3pci_intr_evcnt;
1750 pc->pc_intr_establish = pq3pci_intr_establish;
1751 pc->pc_intr_disestablish = pq3pci_intr_disestablish;
1752 pc->pc_intr_type = pq3pci_intr_type;
1753 pc->pc_intr_alloc = pq3pci_intr_alloc;
1754 pc->pc_intr_release = pq3pci_intr_release;
1755 pc->pc_intr_setattr = genppc_pci_intr_setattr;
1756 pc->pc_intx_alloc = genppc_pci_intx_alloc;
1757
1758 pc->pc_msi_v = sc;
1759 pc->pc_msi_alloc = pq3pci_msi_alloc;
1760
1761 pc->pc_msix_v = sc;
1762 genppc_pci_chipset_msix_init(pc);
1763
1764 pc->pc_conf_interrupt = pq3pci_conf_interrupt;
1765 pc->pc_decompose_tag = pq3pci_decompose_tag;
1766
1767 /*
1768 * This is a horrible kludge but it makes life easier.
1769 */
1770 pc->pc_addr = (void *)(sc->sc_bsh + PEX_CONFIG_ADDR);
1771 pc->pc_data = (void *)(sc->sc_bsh + PEX_CONFIG_DATA);
1772 pc->pc_bus = 0;
1773 pc->pc_memt = &sc->sc_pci_mem_bst.bs_tag;
1774 pc->pc_iot = &sc->sc_pci_io_bst.bs_tag;
1775
1776 SIMPLEQ_INIT(&pc->pc_pbi);
1777
1778 return pc;
1779 }
1780