pq3pci.c revision 1.1.2.1 1 /* $NetBSD: pq3pci.c,v 1.1.2.1 2011/01/07 01:26:20 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.1.2.1 2011/01/07 01:26:20 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 (valid_iwins == 0) {
751 struct pq3pci_iwin iwin = {
752 .pitar = 0,
753 .piwbar = 0,
754 .piwbear = 0,
755 .piwar = PEXIWAR_EN|PEXIWAR_PF|PEXIWAR_TRGT_LOCALMEM
756 |PEXIWAR_RTT_MEM_SNOOP|PEXIWAR_WTT_MEM_SNOOP
757 |__SHIFTIN(30-__builtin_clz(pmemsize),PEXIWAR_IWS),
758 };
759 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXITAR2, iwin.pitar);
760 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWBAR2, iwin.piwbar);
761 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWBEAR2, iwin.piwbear);
762 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWAR2, iwin.piwar);
763
764 if (!pq3pci_iwin_setup(sc, 2, &iwin)) {
765 aprint_error(": error creating inbound window\n");
766 return;
767 }
768
769 }
770
771 if (valid_owins == 0) {
772 u_long membase, iobase;
773 error = extent_alloc(pcimem_ex, PCI_MEMSIZE, PCI_MEMSIZE,
774 PCI_MEMSIZE, EX_WAITOK, &membase);
775 if (error) {
776 aprint_error(
777 ": error allocating address space for %s: %d\n",
778 "PCI memory", error);
779 return;
780 }
781 struct pq3pci_owin owin1 = {
782 .potar = membase >> 12,
783 .potear = 0,
784 .powbar = membase >> 12,
785 .powar = PEXOWAR_EN|PEXOWAR_TC0
786 |PEXOWAR_RTT_MEM|PEXOWAR_WTT_MEM
787 |__SHIFTIN(ilog2(PCI_MEMSIZE)-1,PEXOWAR_OWS),
788 };
789 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTAR1, owin1.potar);
790 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTEAR1, owin1.potear);
791 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWBAR1, owin1.powbar);
792 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWAR1, owin1.powar);
793 if (!pq3pci_owin_setup(sc, 1, &owin1)) {
794 aprint_error(
795 ": error creating bus space for %s\n",
796 "PCI memory");
797 return;
798 }
799
800 error = extent_alloc(pciio_ex, PCI_IOSIZE, PCI_IOSIZE,
801 PCI_IOSIZE, EX_WAITOK, &iobase);
802 if (error) {
803 aprint_error(
804 ": error allocating address space for %s: %d\n",
805 "PCI I/O space", error);
806 return;
807 }
808 struct pq3pci_owin owin2 = {
809 .potar = 0,
810 .potear = 0,
811 .powbar = iobase >> 12,
812 .powar = PEXOWAR_EN|PEXOWAR_TC0
813 |PEXOWAR_RTT_IO|PEXOWAR_WTT_IO
814 |__SHIFTIN(ilog2(PCI_IOSIZE)-1,PEXOWAR_OWS),
815 };
816 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTAR2, owin2.potar);
817 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTEAR2, owin2.potear);
818 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWBAR2, owin2.powbar);
819 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWAR2, owin2.powar);
820 if (!pq3pci_owin_setup(sc, 2, &owin2)) {
821 aprint_error(
822 ": error creating bus space for %s\n",
823 "PCI I/O space");
824 return;
825 }
826
827 struct extent *ioext = extent_create("pciio", 0, PCI_IOSIZE,
828 M_DEVBUF, NULL, 0, EX_NOWAIT);
829 struct extent *memext = extent_create("pcimem", membase,
830 membase + PCI_MEMSIZE, M_DEVBUF, NULL, 0, EX_NOWAIT);
831
832 error = pci_configure_bus(pc, ioext, memext, NULL, 0,
833 curcpu()->ci_ci.dcache_line_size);
834
835 extent_destroy(ioext);
836 extent_destroy(memext);
837
838 if (error) {
839 aprint_normal(": configuration failed\n");
840 return;
841 }
842 }
843 #endif
844
845 aprint_normal(": %s controller%s\n", buf, "");
846
847 struct pcibus_attach_args pba;
848 memset(&pba, 0, sizeof(pba));
849
850 pba.pba_flags = sc->sc_pba_flags | PCI_FLAGS_MSI_OKAY
851 | PCI_FLAGS_MSIX_OKAY;
852 if (pba.pba_flags & PCI_FLAGS_IO_ENABLED)
853 pba.pba_iot = pc->pc_iot;
854 if (pba.pba_flags & PCI_FLAGS_MEM_ENABLED)
855 pba.pba_memt = pc->pc_memt;
856 pba.pba_dmat = cna->cna_dmat;
857 pba.pba_pc = pc;
858 pba.pba_bus = 0;
859
860 /*
861 * Program BAR0 so that MSIs can work.
862 */
863 pci_conf_write(pc, 0, PCI_BAR0, sc->sc_bst->pbs_offset);
864 pcireg_t cmdsts = pci_conf_read(pc, 0, PCI_COMMAND_STATUS_REG);
865 cmdsts |= PCI_COMMAND_INTERRUPT_DISABLE;
866 pci_conf_write(pc, 0, PCI_COMMAND_STATUS_REG, cmdsts);
867
868 #if 0
869 /*
870 *
871 */
872 pq3pci_intr_source_lookup(sc, PIH_MAKE(0, IST_LEVEL, 0));
873 #endif
874 #if 0
875 if (sc->sc_pcie)
876 pci_conf_print(pc, 0, NULL);
877 #endif
878
879 config_found_ia(self, "pcibus", &pba, pcibusprint);
880 }
881
882 static void
883 pq3pci_attach_hook(device_t parent, device_t self,
884 struct pcibus_attach_args *pba)
885 {
886 /* do nothing */
887 }
888
889 static int
890 pq3pci_bus_maxdevs(void *v, int busno)
891 {
892 struct pq3pci_softc * const sc = v;
893 return sc->sc_pcie && busno < 2 ? 1 : 32;
894 }
895
896 static void
897 pq3pci_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func)
898 {
899 if (bus)
900 *bus = (tag >> 16) & 0xff;
901 if (dev)
902 *dev = (tag >> 11) & 0x1f;
903 if (func)
904 *func = (tag >> 8) & 0x07;
905 }
906
907 static pcitag_t
908 pq3pci_make_tag(void *v, int bus, int dev, int func)
909 {
910 return (bus << 16) | (dev << 11) | (func << 8);
911 }
912
913 static inline pcitag_t
914 pq3pci_config_addr_read(pci_chipset_tag_t pc)
915 {
916 pcitag_t v;
917 __asm volatile("lwz\t%0, 0(%1)" : "=r"(v) : "b"(pc->pc_addr));
918 __asm volatile("mbar\n\tmsync");
919 return v;
920 }
921
922 static inline void
923 pq3pci_config_addr_write(pci_chipset_tag_t pc, pcitag_t v)
924 {
925 __asm volatile("stw\t%0, 0(%1)" :: "r"(v), "b"(pc->pc_addr));
926 __asm volatile("mbar\n\tmsync");
927 }
928
929 static inline pcireg_t
930 pq3pci_config_data_read(pci_chipset_tag_t pc)
931 {
932 pcireg_t v;
933 __asm volatile("lwbrx\t%0, 0, %1" : "=r"(v) : "b"(pc->pc_data));
934 __asm volatile("mbar\n\tmsync");
935 return v;
936 }
937
938 static inline void
939 pq3pci_config_data_write(pci_chipset_tag_t pc, pcireg_t v)
940 {
941 __asm volatile("stwbrx\t%0, 0, %1" :: "r"(v), "r"(pc->pc_data));
942 __asm volatile("mbar\n\tmsync");
943 }
944
945 static pcireg_t
946 pq3pci_conf_read(void *v, pcitag_t tag, int reg)
947 {
948 struct pq3pci_softc * const sc = v;
949 struct genppc_pci_chipset * const pc = &sc->sc_pc;
950
951 if (reg >= 256) {
952 if (!sc->sc_pcie)
953 return 0xffffffff;
954 reg = (reg & 0xff) | ((reg & 0xf00) << 16);
955 }
956 if (sc->sc_pcie && ((tag >> 16) & 0xff) != 0) {
957 // pcireg_t slot_status = pci_conf_read(pc, 0, 0x64);
958 // printf("%s: tag 0x0 slot status: %#x\n",__func__, slot_status);
959 // if ((slot_status & __BIT(6+16)) == 0)
960 // printf(" addr=%#llx ", tag | reg | PEX_CONFIG_ADDR_EN);
961 // return 0xffffffff;
962 }
963
964 mutex_spin_enter(sc->sc_conf_lock);
965
966 pq3pci_config_addr_write(pc, tag | reg | PEX_CONFIG_ADDR_EN);
967 pcireg_t rv = pq3pci_config_data_read(pc);
968
969 mutex_spin_exit(sc->sc_conf_lock);
970
971 #if 0
972 uint32_t err = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PEX_ERR_DR);
973 if (err & PEXERRDR_ICCA) {
974 aprint_error_dev(sc->sc_dev, "%s: tag %#x reg %#x icca: %#x\n",
975 __func__, tag, reg, pq3pci_config_addr_read(pc));
976 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEX_ERR_DR,
977 PEXERRDR_ICCA);
978 }
979 #endif
980 return rv;
981 }
982
983 static void
984 pq3pci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
985 {
986 struct pq3pci_softc * const sc = v;
987 struct genppc_pci_chipset * const pc = &sc->sc_pc;
988
989 if (reg >= 256) {
990 if (!sc->sc_pcie)
991 return;
992 reg = (reg & 0xff) | ((reg & 0xf00) << 16);
993 }
994
995 mutex_spin_enter(sc->sc_conf_lock);
996
997 #if 0
998 aprint_error_dev(sc->sc_dev, "%s: tag %#x reg %#x data %#x\n",
999 __func__, tag, reg, data);
1000 #endif
1001 pq3pci_config_addr_write(pc, tag | reg | PEX_CONFIG_ADDR_EN);
1002 pq3pci_config_data_write(pc, data);
1003
1004 mutex_spin_exit(sc->sc_conf_lock);
1005 }
1006
1007 static int
1008 pq3pci_conf_hook(pci_chipset_tag_t pc, int bus, int dev, int func,
1009 pcireg_t id)
1010 {
1011 struct pq3pci_softc * const sc = pc->pc_conf_v;
1012 if (sc->sc_pcie && bus != 0) {
1013 pcireg_t slot_status = pci_conf_read(pc, 0, 0x64);
1014 if ((slot_status & __BIT(6+16)) == 0)
1015 return 0;
1016 }
1017 if (!sc->sc_pcie && bus == 0 && dev == 0) {
1018 return PCI_CONF_DEFAULT ^ (PCI_CONF_MAP_IO|PCI_CONF_MAP_MEM|PCI_CONF_MAP_ROM);
1019 }
1020 return PCI_CONF_DEFAULT;
1021 }
1022
1023 static void
1024 pq3pci_msi_group_setup(struct pq3pci_msigroup *msig, u_int group, int ipl)
1025 {
1026 const char (*intr_names)[8] = msi_intr_names[group];
1027
1028 KASSERT(ipl == IPL_VM);
1029
1030 pq3pci_msigroups[group] = msig;
1031 msig->msig_group = group;
1032 msig->msig_free_mask = ~0 << (group == 0);
1033 msig->msig_ipl = ipl;
1034 msig->msig_lock = mutex_obj_alloc(MUTEX_DEFAULT, ipl);
1035 msig->msig_ih = intr_establish(msig->msig_group, ipl, IST_MSIGROUP,
1036 pq3pci_msi_intr, msig);
1037 msig->msig_msir = OPENPIC_BASE + OPENPIC_MSIR(msig->msig_group);
1038 for (u_int i = 0; i < __arraycount(msig->msig_ihands); i++) {
1039 struct pq3pci_msihand * const msih = msig->msig_ihands + i;
1040 msih->msih_ih.ih_class = IH_MSI;
1041 msih->msih_ih.ih_func = pq3pci_msi_spurious_intr;
1042 msih->msih_ih.ih_arg = msih;
1043 msih->msih_group = msig;
1044 evcnt_attach_dynamic(&msih->msih_ev, EVCNT_TYPE_INTR,
1045 NULL, intr_names[i], "intr");
1046 evcnt_attach_dynamic(&msih->msih_ev_spurious, EVCNT_TYPE_INTR,
1047 &msih->msih_ev, intr_names[i], "spurious intr");
1048 }
1049 }
1050
1051 static pci_intr_handle_t
1052 pq3pci_msi_alloc(int ipl, u_int rmsi)
1053 {
1054 size_t freegroup = 0;
1055 size_t maplen = __arraycount(pq3pci_msigroups);
1056 KASSERT(rmsi <= 5);
1057 uint32_t bitmap[maplen];
1058
1059 for (u_int i = 0; i < maplen; i++) {
1060 struct pq3pci_msigroup * const msig = pq3pci_msigroups[i];
1061 if (msig == NULL) {
1062 bitmap[i] = 0;
1063 if (freegroup == 0)
1064 freegroup = i + 1;
1065 continue;
1066 }
1067 /*
1068 * If this msigroup has the wrong IPL or there's nothing
1069 * free, try the next one.
1070 */
1071 if (msig->msig_ipl != ipl || msig->msig_free_mask == 0) {
1072 bitmap[i] = 0;
1073 continue;
1074 }
1075
1076 bitmap[i] = msig->msig_free_mask;
1077 }
1078 for (u_int i = 0; i < maplen; i++) {
1079 uint32_t mapbits = bitmap[i];
1080 u_int n = ffs(mapbits);
1081 if (n--) {
1082 return PIH_MAKE(i * 32 + n, IST_MSI, 0);
1083 }
1084 }
1085
1086 if (freegroup-- == 0)
1087 return 0;
1088
1089 struct pq3pci_msigroup * const msig =
1090 kmem_zalloc(sizeof(*msig), KM_SLEEP);
1091 KASSERT(msig != NULL);
1092 pq3pci_msi_group_setup(msig, freegroup, ipl);
1093 u_int n = ffs(msig->msig_free_mask) - 1;
1094 return PIH_MAKE(freegroup * 32 + n, IST_MSI, 0);
1095 }
1096
1097 static struct pq3pci_msihand *
1098 pq3pci_msi_lookup(pci_intr_handle_t handle)
1099 {
1100 const int irq = PIH_IRQ(handle);
1101 KASSERT(irq < 256);
1102 struct pq3pci_msigroup * const msig = pq3pci_msigroups[irq / 32];
1103 KASSERT(msig != NULL);
1104 return &msig->msig_ihands[irq & 31];
1105 }
1106
1107 static struct pq3pci_msihand *
1108 pq3pci_msi_claim(pci_intr_handle_t handle)
1109 {
1110 const int irq = PIH_IRQ(handle);
1111 uint32_t irq_mask = __BIT(irq & 31);
1112 KASSERT(irq < 256);
1113 struct pq3pci_msigroup * const msig = pq3pci_msigroups[irq / 32];
1114 KASSERT(msig != NULL);
1115 struct pq3pci_msihand * const msih = &msig->msig_ihands[irq & 31];
1116 mutex_spin_enter(msig->msig_lock);
1117 KASSERT(msig->msig_free_mask & irq_mask);
1118 msig->msig_free_mask ^= irq_mask;
1119 mutex_spin_exit(msig->msig_lock);
1120 return msih;
1121 }
1122
1123 static struct pq3pci_intrsource *
1124 pq3pci_intr_source_lookup(struct pq3pci_softc *sc, pci_intr_handle_t handle)
1125 {
1126 struct pq3pci_intrsource *pis;
1127 SIMPLEQ_FOREACH(pis, &pq3pci_intrsources, pis_link) {
1128 if (pis->pis_handle == handle)
1129 return pis;
1130 }
1131 pis = kmem_zalloc(sizeof(*pis), KM_SLEEP);
1132 pq3pci_intr_source_setup(sc, pis, handle);
1133 return pis;
1134 }
1135
1136 static pci_intr_handle_t
1137 pq3pci_intr_handle_lookup(struct pq3pci_softc *sc, struct pci_attach_args *pa)
1138 {
1139 prop_dictionary_t entry;
1140
1141 if (sc->sc_pcie) do {
1142 pcireg_t msictl;
1143 int msioff;
1144 if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_MSI,
1145 &msioff, &msictl))
1146 break;
1147 msictl = pci_conf_read(pa->pa_pc, pa->pa_tag, msioff);
1148 msictl &= ~PCI_MSI_CTL_MSI_ENABLE;
1149 msictl &= ~(PCI_MSI_CTL_MME_MASK << PCI_MSI_CTL_MME_SHIFT);
1150 int rmsi = (msictl >> PCI_MSI_CTL_MMC_SHIFT) & PCI_MSI_CTL_MMC_MASK;
1151 pci_conf_write(pa->pa_pc, pa->pa_tag, msioff, msictl);
1152 pci_intr_handle_t handle = pq3pci_msi_alloc(IPL_VM, rmsi);
1153 struct pq3pci_msihand * const msih = pq3pci_msi_lookup(handle);
1154 msih->msih_tag = pa->pa_tag;
1155 msih->msih_msioff = msioff;
1156 return handle;
1157 } while (false);
1158
1159
1160 if (sc->sc_intrmask == 0) {
1161 entry = prop_dictionary_get(sc->sc_intrmap, "000000");
1162 } else {
1163 char prop_name[8];
1164 u_int intrinc = __LOWEST_SET_BIT(sc->sc_intrmask);
1165 pcitag_t tag = (pa->pa_intrpin - PCI_INTERRUPT_PIN_A) * intrinc;
1166
1167 snprintf(prop_name, sizeof(prop_name), "%06x",
1168 tag & sc->sc_intrmask);
1169
1170 #if 0
1171 printf("%s: %#x %#x %u (%u) -> %#x & %#x -> %#x <%s>\n",
1172 __func__, pa->pa_tag, pa->pa_intrtag, pa->pa_intrpin, pa->pa_rawintrpin,
1173 tag, sc->sc_intrmask, tag & sc->sc_intrmask, prop_name);
1174 #endif
1175
1176 entry = prop_dictionary_get(sc->sc_intrmap, prop_name);
1177 }
1178 KASSERT(entry != NULL);
1179 KASSERT(prop_object_type(entry) == PROP_TYPE_DICTIONARY);
1180
1181 prop_number_t pn_irq = prop_dictionary_get(entry, "interrupt");
1182 KASSERT(pn_irq != NULL);
1183 KASSERT(prop_object_type(pn_irq) == PROP_TYPE_NUMBER);
1184 int irq = prop_number_unsigned_integer_value(pn_irq);
1185 prop_number_t pn_ist = prop_dictionary_get(entry, "type");
1186 KASSERT(pn_ist != NULL);
1187 KASSERT(prop_object_type(pn_ist) == PROP_TYPE_NUMBER);
1188 int ist = prop_number_unsigned_integer_value(pn_ist);
1189
1190 return PIH_MAKE(irq, ist, 0);
1191 }
1192
1193 static int
1194 pq3pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *handlep)
1195 {
1196 struct pq3pci_softc * const sc = pa->pa_pc->pc_intr_v;
1197
1198 if (pa->pa_intrpin == PCI_INTERRUPT_PIN_NONE)
1199 return ENOENT;
1200
1201 *handlep = pq3pci_intr_handle_lookup(sc, pa);
1202
1203 return 0;
1204 }
1205
1206 static const char *
1207 pq3pci_intr_string(void *v, pci_intr_handle_t handle)
1208 {
1209 if (PIH_IST(handle) == IST_MSI) {
1210 const char (*intr_names)[8] = msi_intr_names[0];
1211 return intr_names[PIH_IRQ(handle)];
1212 }
1213
1214 return intr_string(PIH_IRQ(handle), PIH_IST(handle));
1215 }
1216
1217 static const struct evcnt *
1218 pq3pci_intr_evcnt(void *v, pci_intr_handle_t handle)
1219 {
1220 struct pq3pci_softc * const sc = v;
1221 struct pq3pci_intrsource * const pis =
1222 pq3pci_intr_source_lookup(sc, handle);
1223
1224 KASSERT(pis != NULL);
1225
1226 return &pis->pis_ev;
1227 }
1228
1229 static void *
1230 pq3pci_intr_establish(void *v, pci_intr_handle_t handle, int ipl,
1231 int (*func)(void *), void *arg)
1232 {
1233 struct pq3pci_softc * const sc = v;
1234
1235 if (0) {
1236 struct pq3pci_callhand * const pch =
1237 kmem_zalloc(sizeof(*pch), KM_SLEEP);
1238 KASSERT(pch);
1239 pch->pch_ih.ih_arg = arg;
1240 pch->pch_ih.ih_func = func;
1241 pch->pch_ih.ih_sc = sc;
1242 pch->pch_ipl = ipl;
1243
1244 callout_init(&pch->pch_callout, 0);
1245 callout_reset(&pch->pch_callout, 1, pq3pci_pch_callout, pch);
1246
1247 return pch;
1248 }
1249
1250 const int ist = PIH_IST(handle);
1251
1252 if (ist == IST_MSI) {
1253 pci_chipset_tag_t pc = &sc->sc_pc;
1254 struct pq3pci_msihand * const msih = pq3pci_msi_claim(handle);
1255 pcireg_t cmdsts, msictl;
1256
1257 if (msih == NULL)
1258 return NULL;
1259
1260 struct pq3pci_msigroup * const msig = msih->msih_group;
1261 const pcitag_t tag = msih->msih_tag;
1262
1263 mutex_spin_enter(msig->msig_lock);
1264 msih->msih_ih.ih_class = IH_MSI;
1265 msih->msih_ih.ih_arg = arg;
1266 msih->msih_ih.ih_func = func;
1267 msih->msih_ih.ih_sc = sc;
1268
1269 int off = msih->msih_msioff;
1270 msictl = pci_conf_read(pc, tag, off);
1271
1272 /*
1273 * The PCSRBAR has already been setup as a 1:1 BAR so we point
1274 * MSIs at the MSII register in the OpenPIC.
1275 */
1276 off += 4;
1277 pci_conf_write(pc, tag, off,
1278 sc->sc_bst->pbs_offset + OPENPIC_BASE + OPENPIC_MSIIR);
1279
1280 /*
1281 * Upper address is going to be 0.
1282 */
1283 if (msictl & PCI_MSI_CTL_64BIT_ADDR) {
1284 off += 4;
1285 pci_conf_write(pc, tag, off, 0);
1286 }
1287
1288 /*
1289 * Set the magic value. Since PCI writes this to the least
1290 * significant byte of AD[31:0], let's hope the bridge byte
1291 * swaps to so it's the most significant bytes or nothing is
1292 * going to happen.
1293 */
1294 off += 4;
1295 pci_conf_write(pc, tag, off, PIH_IRQ(handle));
1296
1297 /*
1298 * Should the driver do this? How would it know to do it?
1299 */
1300 if (msictl & PCI_MSI_CTL_PERVEC_MASK) {
1301 off += 4;
1302 pci_conf_write(pc, tag, off, 0);
1303 }
1304
1305 /*
1306 * Let's make sure he won't raise any INTx. Technically
1307 * setting MSI enable will prevent that as well but might
1308 * as well be as safe as possible.
1309 */
1310 cmdsts = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
1311 cmdsts |= PCI_COMMAND_INTERRUPT_DISABLE;
1312 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, cmdsts);
1313
1314 #if 1
1315 /*
1316 * Now we can enable the MSI
1317 */
1318 msictl |= PCI_MSI_CTL_MSI_ENABLE;
1319 pci_conf_write(pc, tag, msih->msih_msioff, msictl);
1320 #endif
1321
1322 mutex_spin_exit(msig->msig_lock);
1323
1324 #if 0
1325 struct pq3pci_callhand * const pch =
1326 kmem_zalloc(sizeof(*pch), KM_SLEEP);
1327 KASSERT(pch);
1328
1329 pch->pch_ih.ih_arg = msig;
1330 pch->pch_ih.ih_func = pq3pci_msi_intr;
1331 #if 1
1332 pch->pch_ih.ih_arg = arg;
1333 pch->pch_ih.ih_func = func;
1334 #endif
1335 pch->pch_ih.ih_sc = sc;
1336 pch->pch_ipl = ipl;
1337
1338 callout_init(&pch->pch_callout, 0);
1339 callout_reset(&pch->pch_callout, 1, pq3pci_pch_callout, pch);
1340
1341 #if 1
1342 return pch;
1343 #endif
1344 #endif
1345
1346 return msih;
1347 } else {
1348 struct pq3pci_intrsource * const pis =
1349 pq3pci_intr_source_lookup(sc, handle);
1350 KASSERT(pis != NULL);
1351
1352 struct pq3pci_intrhand * const pih =
1353 kmem_zalloc(sizeof(*pih), KM_SLEEP);
1354
1355 if (pih == NULL)
1356 return NULL;
1357
1358 pih->pih_ih.ih_class = IH_INTX;
1359 pih->pih_ih.ih_func = func;
1360 pih->pih_ih.ih_arg = arg;
1361 pih->pih_ih.ih_sc = sc;
1362 pih->pih_ipl = ipl;
1363 pih->pih_source = pis;
1364
1365 mutex_spin_enter(pis->pis_lock);
1366 SIMPLEQ_INSERT_TAIL(&pis->pis_ihands, pih, pih_link);
1367 mutex_spin_exit(pis->pis_lock);
1368
1369 return pih;
1370 }
1371 }
1372
1373 static void
1374 pq3pci_intr_disestablish(void *v, void *ih)
1375 {
1376 struct pq3pci_genihand * const gih = ih;
1377
1378 if (gih->ih_class == IH_INTX) {
1379 struct pq3pci_intrhand * const pih = ih;
1380 struct pq3pci_intrsource * const pis = pih->pih_source;
1381
1382 mutex_spin_enter(pis->pis_lock);
1383 SIMPLEQ_REMOVE(&pis->pis_ihands, pih, pq3pci_intrhand, pih_link);
1384 mutex_spin_exit(pis->pis_lock);
1385
1386 kmem_free(pih, sizeof(*pih));
1387 return;
1388 }
1389 struct pq3pci_msihand * const msih = ih;
1390 struct pq3pci_msigroup * const msig = msih->msih_group;
1391 struct genppc_pci_chipset * const pc = &msih->msih_ih.ih_sc->sc_pc;
1392 const pcitag_t tag = msih->msih_tag;
1393
1394 mutex_spin_enter(msig->msig_lock);
1395
1396 /*
1397 * disable the MSI
1398 */
1399 pcireg_t msictl = pci_conf_read(pc, tag, msih->msih_msioff);
1400 msictl &= ~PCI_MSI_CTL_MSI_ENABLE;
1401 pci_conf_write(pc, tag, msih->msih_msioff, msictl);
1402
1403 msih->msih_ih.ih_func = pq3pci_msi_spurious_intr;
1404 msih->msih_ih.ih_arg = msig;
1405 msih->msih_ih.ih_sc = NULL;
1406 msih->msih_tag = 0;
1407 msih->msih_msioff = 0;
1408 mutex_spin_exit(msig->msig_lock);
1409 }
1410
1411 static void
1412 pq3pci_conf_interrupt(pci_chipset_tag_t pc, int bus, int dev, int pin,
1413 int swiz, int *iline)
1414 {
1415 }
1416
1417 static pci_chipset_tag_t
1418 pq3pci_pci_chipset_init(struct pq3pci_softc *sc)
1419 {
1420 struct genppc_pci_chipset * const pc = &sc->sc_pc;
1421
1422 pc->pc_conf_v = sc;
1423 pc->pc_attach_hook = pq3pci_attach_hook;
1424 pc->pc_bus_maxdevs = pq3pci_bus_maxdevs;
1425 pc->pc_make_tag = pq3pci_make_tag;
1426 pc->pc_conf_read = pq3pci_conf_read;
1427 pc->pc_conf_write = pq3pci_conf_write;
1428 #ifdef PCI_NETBSD_CONFIGURE
1429 pc->pc_conf_hook = pq3pci_conf_hook;
1430 #endif
1431
1432 pc->pc_intr_v = sc;
1433 pc->pc_intr_map = pq3pci_intr_map;
1434 pc->pc_intr_string = pq3pci_intr_string;
1435 pc->pc_intr_evcnt = pq3pci_intr_evcnt;
1436 pc->pc_intr_establish = pq3pci_intr_establish;
1437 pc->pc_intr_disestablish = pq3pci_intr_disestablish;
1438 pc->pc_conf_interrupt = pq3pci_conf_interrupt;
1439 pc->pc_decompose_tag = pq3pci_decompose_tag;
1440 pc->pc_conf_hook = pq3pci_conf_hook;
1441
1442 /*
1443 * This is a horrible kludge but it makes life easier.
1444 */
1445 pc->pc_addr = (void *)(sc->sc_bsh + PEX_CONFIG_ADDR);
1446 pc->pc_data = (void *)(sc->sc_bsh + PEX_CONFIG_DATA);
1447 pc->pc_bus = 0;
1448 pc->pc_memt = &sc->sc_pci_mem_bst.bs_tag;
1449 pc->pc_iot = &sc->sc_pci_io_bst.bs_tag;
1450
1451 SIMPLEQ_INIT(&pc->pc_pbi);
1452
1453 return pc;
1454 }
1455