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