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