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