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