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