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
108const 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
199static const struct e500_truthtab pq3pci_pci_pcix[] = {
200#ifdef MPC8548
201    PORDEVSR_TRUTH_ENCODE(SVR_MPC8548v1, 1, PCI1, PCIX, 1),
202#endif
203};
204
205static 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
217struct 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
227typedef enum { IH_NONE, IH_INTX, IH_MSI, IH_MSIX } pq3pci_intr_class_t;
228
229struct 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
236struct 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
244struct 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
255struct 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
266struct 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
275struct 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
285struct 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
302static int pq3pci_cpunode_match(device_t, cfdata_t, void *aux);
303static void pq3pci_cpunode_attach(device_t, device_t, void *aux);
304static pci_chipset_tag_t pq3pci_pci_chipset_init(struct pq3pci_softc *);
305
306static ONCE_DECL(pq3pci_init_once);
307static kmutex_t pq3pci_intrsources_lock;
308static kmutex_t pq3pci_msigroups_lock;
309static SIMPLEQ_HEAD(,pq3pci_intrsource) pq3pci_intrsources
310    = SIMPLEQ_HEAD_INITIALIZER(pq3pci_intrsources);
311static struct pq3pci_msigroup *pq3pci_msigroups[8];
312
313static struct pq3pci_intrsource *
314    pq3pci_intr_source_lookup(struct pq3pci_softc *, pci_intr_handle_t);
315
316static 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
392CFATTACH_DECL_NEW(pq3pci_cpunode, sizeof(struct pq3pci_softc),
393    pq3pci_cpunode_match, pq3pci_cpunode_attach, NULL, NULL);
394
395CFATTACH_DECL_NEW(pq3pcie_cpunode, sizeof(struct pq3pci_softc),
396    pq3pci_cpunode_match, pq3pci_cpunode_attach, NULL, NULL);
397
398int
399pq3pci_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
408struct pq3pci_owin {
409	uint32_t potar;
410	uint32_t potear;
411	uint32_t powbar;
412	uint32_t powar;
413};
414
415static void
416pq3pci_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
458static bool
459pq3pci_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
502struct pq3pci_iwin {
503	uint32_t pitar;
504	uint32_t piwbar;
505	uint32_t piwbear;
506	uint32_t piwar;
507};
508
509static bool
510pq3pci_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
567static int
568pq3pci_msi_spurious_intr(void *v)
569{
570	(void) v;
571
572	return 0;
573}
574
575static int
576pq3pci_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
639static int
640pq3pci_onchip_intr(void *v)
641{
642	panic(__func__);
643}
644
645static int
646pq3pci_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
678static void
679pq3pci_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
698static bool
699pq3pci_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
726static int
727pq3pci_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
739void
740pq3pci_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
1003static void
1004pq3pci_attach_hook(device_t parent, device_t self,
1005	struct pcibus_attach_args *pba)
1006{
1007	/* do nothing */
1008}
1009
1010static int
1011pq3pci_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
1017static void
1018pq3pci_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
1028static pcitag_t
1029pq3pci_make_tag(void *v, int bus, int dev, int func)
1030{
1031	return (bus << 16) | (dev << 11) | (func << 8);
1032}
1033
1034#if 0
1035static inline pcitag_t
1036pq3pci_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
1045static inline void
1046pq3pci_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
1052static inline pcireg_t
1053pq3pci_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
1061static inline void
1062pq3pci_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
1068static pcireg_t
1069pq3pci_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
1108static void
1109pq3pci_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
1135static int
1136pq3pci_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
1151static void
1152pq3pci_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
1182static struct pq3pci_msihand *
1183pq3pci_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
1192static struct pq3pci_msihand *
1193pq3pci_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
1207static pci_intr_handle_t
1208pq3pci_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
1269static int
1270pq3pci_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
1314static void
1315pq3pci_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
1329static struct pq3pci_intrsource *
1330pq3pci_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
1347static pci_intr_handle_t
1348pq3pci_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
1405static int
1406pq3pci_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
1418static const char *
1419pq3pci_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
1430static const struct evcnt *
1431pq3pci_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
1448static void *
1449pq3pci_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
1551static void
1552pq3pci_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
1590static pci_intr_type_t
1591pq3pci_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
1600static int
1601pq3pci_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
1671static void
1672pq3pci_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
1685static void
1686pq3pci_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 */
1700static int
1701pq3pci_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
1734static pci_chipset_tag_t
1735pq3pci_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