pq3pci.c revision 1.30
1/*	$NetBSD: pq3pci.c,v 1.30 2022/01/11 22:45:56 andvar 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.30 2022/01/11 22:45:56 andvar 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_integer_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	mutex_init(&pq3pci_intrsources_lock, MUTEX_DEFAULT, IPL_VM);
731	mutex_init(&pq3pci_msigroups_lock, MUTEX_DEFAULT, IPL_VM);
732
733	return 0;
734}
735
736void
737pq3pci_cpunode_attach(device_t parent, device_t self, void *aux)
738{
739	struct cpunode_softc * const psc = device_private(parent);
740	struct pq3pci_softc * const sc = device_private(self);
741	struct cpunode_attach_args * const cna = aux;
742	struct cpunode_locators * const cnl = &cna->cna_locs;
743	char buf[32];
744
745	sc->sc_dev = self;
746	sc->sc_bst = cna->cna_memt;
747	psc->sc_children |= cna->cna_childmask;
748	sc->sc_pcie = strcmp(cnl->cnl_name, "pcie") == 0;
749
750	RUN_ONCE(&pq3pci_init_once, pq3pci_once_init);
751
752	const uint32_t pordevsr = cpu_read_4(GLOBAL_BASE + PORDEVSR);
753	if (sc->sc_pcie) {
754		u_int lanes = e500_truth_decode(cnl->cnl_instance, pordevsr,
755		    pq3pci_pcie_lanes, __arraycount(pq3pci_pcie_lanes), 0);
756		if (lanes == 0) {
757			aprint_normal(": disabled\n");
758			return;
759		}
760		snprintf(buf, sizeof(buf), "PCI-Express x%u", lanes);
761	} else {
762		bool pcix_p = e500_truth_decode(cnl->cnl_instance, pordevsr,
763		    pq3pci_pci_pcix, __arraycount(pq3pci_pci_pcix), 0);
764		u_int width = e500_truth_decode(cnl->cnl_instance, pordevsr,
765		    pq3pci_pci_pci32, __arraycount(pq3pci_pci_pci32), 32);
766		snprintf(buf, sizeof(buf), "%u-bit PCI%s",
767		    width, (pcix_p ? "X" : ""));
768	}
769
770	if (!pq3pci_intrmap_setup(sc, cnl))
771		return;
772
773	evcnt_attach_dynamic(&sc->sc_ev_spurious, EVCNT_TYPE_INTR, NULL,
774	    device_xname(self), "spurious intr");
775
776	int error = bus_space_map(sc->sc_bst, cnl->cnl_addr, cnl->cnl_size, 0,
777	    &sc->sc_bsh);
778	if (error) {
779		aprint_error(": failed to map registers: %d\n", error);
780		return;
781	}
782
783	u_int valid_owins = 0;
784	for (u_int i = 1, off = PEXOTAR1 - PEXOTAR0;
785	     i < 4; i++, off += PEXOTAR1 - PEXOTAR0) {
786		struct pq3pci_owin owin;
787		owin.potar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
788		    PEXOTAR0 + off);
789		owin.potear = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
790		    PEXOTEAR0 + off);
791		owin.powbar = 0;
792		if (i > 0) {
793			/* Doesn't exist for outbound window 0 */
794			owin.powbar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
795			    PEXOWBAR1 - (PEXOTAR1 - PEXOTAR0) + off);
796		}
797		owin.powar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
798		    PEXOWAR0 + off);
799#if 0
800		aprint_normal_dev(self,
801		    "owin[%u]: potar=%#x potear=%#x powbar=%#x powar=%#x\n",
802		    i, owin.potar, owin.potear, owin.powbar, owin.powar);
803#endif
804		if (owin.powar & PEXOWAR_EN) {
805			valid_owins++;
806			pq3pci_owin_record(sc, i, &owin);
807		}
808	}
809	if (!pq3pci_owin_init(sc, &sc->sc_pci_io_bst, true)
810	    || !pq3pci_owin_init(sc, &sc->sc_pci_mem_bst, false)) {
811		return;
812	}
813#ifndef PCI_NETBSD_CONFIGURE
814	if (valid_owins == 0) {
815		aprint_normal(": %s controller%s\n", buf,
816		    " (disabled)");
817		return;
818	}
819#endif
820
821	u_int valid_iwins = 0;
822	for (u_int i = 0, off = 0; i < 3; i++, off += PEXITAR2 - PEXITAR1) {
823		struct pq3pci_iwin iwin;
824		iwin.pitar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
825		    PEXITAR1 + off);
826		iwin.piwbar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
827		    PEXIWBAR1 + off);
828		if (i > 0) {
829			/* Doesn't exist */
830			iwin.piwbear = bus_space_read_4(sc->sc_bst,
831			    sc->sc_bsh,
832			    PEXIWBEAR2 - (PEXITAR2 - PEXITAR1) + off);
833		} else {
834			iwin.piwbear = 0;
835		}
836		iwin.piwar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
837		    PEXIWAR1 + off);
838#if 0
839		aprint_normal_dev(self,
840		    "iwin[%u]: pitar=%#x piwbar=%#x piwbear=%#x piwar=%#x\n",
841		    i, iwin.pitar, iwin.piwbar, iwin.piwbear, iwin.piwar);
842#endif
843		if (iwin.piwar & PEXIWAR_EN) {
844			valid_iwins++;
845			if (!pq3pci_iwin_setup(sc, i, &iwin))
846				return;
847		}
848	}
849
850	sc->sc_conf_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_VM);
851
852	pci_chipset_tag_t pc = pq3pci_pci_chipset_init(sc);
853
854#ifndef PCI_NETBSD_CONFIGURE
855	if (valid_iwins == 0) {
856		aprint_normal(": %s controller%s\n", buf,
857		    " (disabled)");
858		return;
859	}
860#else
861	if (sc->sc_pcie && pci_conf_read(pc, 0, PEX_LTSSM) < LTSSM_L0) {
862		aprint_normal(": %s controller%s\n", buf,
863		    " (offline)");
864		return;
865	}
866	if (!sc->sc_pcie && (pci_conf_read(pc, 0, PCI_PBFR) & PBFR_PAH)) {
867		aprint_normal(": %s controller%s\n", buf,
868		    " (agent mode)");
869		return;
870	}
871	if (valid_iwins == 0) {
872		struct pq3pci_iwin iwin = {
873		    .pitar = 0,
874		    .piwbar = 0,
875		    .piwbear = 0,
876		    .piwar = PEXIWAR_EN|PEXIWAR_PF|PEXIWAR_TRGT_LOCALMEM
877			|PEXIWAR_RTT_MEM_SNOOP|PEXIWAR_WTT_MEM_SNOOP
878			|__SHIFTIN(30-__builtin_clz(pmemsize),PEXIWAR_IWS),
879		};
880		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXITAR2, iwin.pitar);
881		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWBAR2, iwin.piwbar);
882		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWBEAR2, iwin.piwbear);
883		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWAR2, iwin.piwar);
884
885		if (!pq3pci_iwin_setup(sc, 2, &iwin)) {
886			aprint_error(": error creating inbound window\n");
887			return;
888		}
889
890	}
891
892	if (valid_owins == 0) {
893		u_long membase, iobase;
894		error = extent_alloc(pcimem_ex, PCI_MEMSIZE, PCI_MEMSIZE,
895		   PCI_MEMSIZE, EX_WAITOK, &membase);
896		if (error) {
897			aprint_error(
898			    ": error allocating address space for %s: %d\n",
899			    "PCI memory", error);
900			return;
901		}
902		struct pq3pci_owin owin1 = {
903		    .potar = membase >> 12,
904		    .potear = 0,
905		    .powbar = membase >> 12,
906		    .powar = PEXOWAR_EN|PEXOWAR_TC0
907			|PEXOWAR_RTT_MEM|PEXOWAR_WTT_MEM
908			|__SHIFTIN(ilog2(PCI_MEMSIZE)-1,PEXOWAR_OWS),
909		};
910		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTAR1, owin1.potar);
911		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTEAR1, owin1.potear);
912		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWBAR1, owin1.powbar);
913		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWAR1, owin1.powar);
914		pq3pci_owin_record(sc, 1, &owin1);
915		if (!pq3pci_owin_init(sc, &sc->sc_pci_mem_bst, false)) {
916			return;
917		}
918
919		error = extent_alloc(pciio_ex, PCI_IOSIZE, PCI_IOSIZE,
920		   PCI_IOSIZE, EX_WAITOK, &iobase);
921		if (error) {
922			aprint_error(
923			    ": error allocating address space for %s: %d\n",
924			    "PCI I/O space", error);
925			return;
926		}
927		struct pq3pci_owin owin2 = {
928		    .potar = 0,
929		    .potear = 0,
930		    .powbar = iobase >> 12,
931		    .powar = PEXOWAR_EN|PEXOWAR_TC0
932			|PEXOWAR_RTT_IO|PEXOWAR_WTT_IO
933			|__SHIFTIN(ilog2(PCI_IOSIZE)-1,PEXOWAR_OWS),
934		};
935		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTAR2, owin2.potar);
936		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTEAR2, owin2.potear);
937		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWBAR2, owin2.powbar);
938		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWAR2, owin2.powar);
939		pq3pci_owin_record(sc, 2, &owin1);
940		if (!pq3pci_owin_init(sc, &sc->sc_pci_io_bst, true)) {
941			return;
942		}
943
944		struct pciconf_resources *pcires = pciconf_resource_init();
945
946		pciconf_resource_add(pcires, PCICONF_RESOURCE_IO,
947		    0, PCI_IOSIZE);
948		pciconf_resource_add(pcires, PCICONF_RESOURCE_MEM,
949		    membase, PCI_MEMSIZE);
950
951		error = pci_configure_bus(pc, pcires, 0,
952		    curcpu()->ci_ci.dcache_line_size);
953
954		pciconf_resource_fini(pcires);
955
956		if (error) {
957			aprint_normal(": configuration failed\n");
958			return;
959		}
960	}
961#endif
962
963	aprint_normal(": %s controller%s\n", buf, "");
964
965	struct pcibus_attach_args pba;
966	memset(&pba, 0, sizeof(pba));
967
968	pba.pba_flags = sc->sc_pba_flags | PCI_FLAGS_MSI_OKAY
969	    | PCI_FLAGS_MSIX_OKAY;
970	if (pba.pba_flags & PCI_FLAGS_IO_OKAY)
971		pba.pba_iot = pc->pc_iot;
972	if (pba.pba_flags & PCI_FLAGS_MEM_OKAY)
973		pba.pba_memt = pc->pc_memt;
974	pba.pba_dmat = cna->cna_dmat;
975	pba.pba_pc = pc;
976	pba.pba_bus = 0;
977
978	/*
979	 * Program BAR0 so that MSIs can work.
980	 */
981	pci_conf_write(pc, 0, PCI_BAR0, sc->sc_bst->pbs_offset);
982	pcireg_t cmdsts = pci_conf_read(pc, 0, PCI_COMMAND_STATUS_REG);
983	cmdsts |= PCI_COMMAND_INTERRUPT_DISABLE;
984	pci_conf_write(pc, 0, PCI_COMMAND_STATUS_REG, cmdsts);
985
986#if 0
987	/*
988	 *
989	 */
990	pq3pci_intr_source_lookup(sc, PIH_MAKE(0, IST_LEVEL, 0));
991#endif
992#if 0
993	if (sc->sc_pcie)
994		pci_conf_print(pc, 0, NULL);
995#endif
996
997	config_found(self, &pba, pcibusprint, CFARGS_NONE);
998}
999
1000static void
1001pq3pci_attach_hook(device_t parent, device_t self,
1002	struct pcibus_attach_args *pba)
1003{
1004	/* do nothing */
1005}
1006
1007static int
1008pq3pci_bus_maxdevs(void *v, int busno)
1009{
1010	struct pq3pci_softc * const sc = v;
1011	return sc->sc_pcie && busno < 2 ? 1 : 32;
1012}
1013
1014static void
1015pq3pci_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func)
1016{
1017	if (bus)
1018		*bus = (tag >> 16) & 0xff;
1019	if (dev)
1020		*dev = (tag >> 11) & 0x1f;
1021	if (func)
1022		*func = (tag >> 8) & 0x07;
1023}
1024
1025static pcitag_t
1026pq3pci_make_tag(void *v, int bus, int dev, int func)
1027{
1028	return (bus << 16) | (dev << 11) | (func << 8);
1029}
1030
1031#if 0
1032static inline pcitag_t
1033pq3pci_config_addr_read(pci_chipset_tag_t pc)
1034{
1035	pcitag_t v;
1036        __asm volatile("lwz\t%0, 0(%1)" : "=r"(v) : "b"(pc->pc_addr));
1037        __asm volatile("mbar\n\tmsync");
1038	return v;
1039}
1040#endif
1041
1042static inline void
1043pq3pci_config_addr_write(pci_chipset_tag_t pc, pcitag_t v)
1044{
1045        __asm volatile("stw\t%0, 0(%1)" :: "r"(v), "b"(pc->pc_addr));
1046        __asm volatile("mbar\n\tmsync");
1047}
1048
1049static inline pcireg_t
1050pq3pci_config_data_read(pci_chipset_tag_t pc)
1051{
1052	pcireg_t v;
1053        __asm volatile("lwbrx\t%0, 0, %1" : "=r"(v) : "b"(pc->pc_data));
1054        __asm volatile("mbar\n\tmsync");
1055	return v;
1056}
1057
1058static inline void
1059pq3pci_config_data_write(pci_chipset_tag_t pc, pcireg_t v)
1060{
1061        __asm volatile("stwbrx\t%0, 0, %1" :: "r"(v), "r"(pc->pc_data));
1062        __asm volatile("mbar\n\tmsync");
1063}
1064
1065static pcireg_t
1066pq3pci_conf_read(void *v, pcitag_t tag, int reg)
1067{
1068	struct pq3pci_softc * const sc = v;
1069	struct genppc_pci_chipset * const pc = &sc->sc_pc;
1070
1071	if (reg < 0)
1072		return 0xffffffff;
1073	if (reg >= PCI_CONF_SIZE) {
1074		if (!sc->sc_pcie || reg >= PCI_EXTCONF_SIZE)
1075			return 0xffffffff;
1076		reg = (reg & 0xff) | ((reg & 0xf00) << 16);
1077	}
1078	if (sc->sc_pcie && ((tag >> 16) & 0xff) != 0) {
1079	//	pcireg_t slot_status = pci_conf_read(pc, 0, 0x64);
1080	//	printf("%s: tag 0x0 slot status: %#x\n",__func__, slot_status);
1081	//	if ((slot_status & __BIT(6+16)) == 0)
1082	//		printf(" addr=%#llx ", tag | reg | PEX_CONFIG_ADDR_EN);
1083	//		return 0xffffffff;
1084	}
1085
1086	mutex_spin_enter(sc->sc_conf_lock);
1087
1088	pq3pci_config_addr_write(pc, tag | reg | PEX_CONFIG_ADDR_EN);
1089	pcireg_t rv = pq3pci_config_data_read(pc);
1090
1091	mutex_spin_exit(sc->sc_conf_lock);
1092
1093#if 0
1094	uint32_t err = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PEX_ERR_DR);
1095	if (err & PEXERRDR_ICCA) {
1096		aprint_error_dev(sc->sc_dev, "%s: tag %#x reg %#x icca: %#x\n",
1097		    __func__, tag, reg, pq3pci_config_addr_read(pc));
1098		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEX_ERR_DR,
1099		    PEXERRDR_ICCA);
1100	}
1101#endif
1102	return rv;
1103}
1104
1105static void
1106pq3pci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
1107{
1108	struct pq3pci_softc * const sc = v;
1109	struct genppc_pci_chipset * const pc = &sc->sc_pc;
1110
1111	if (reg < 0)
1112		return;
1113	if (reg >= PCI_CONF_SIZE) {
1114		if (!sc->sc_pcie || reg >= PCI_EXTCONF_SIZE)
1115			return;
1116		reg = (reg & 0xff) | ((reg & 0xf00) << 16);
1117	}
1118
1119	mutex_spin_enter(sc->sc_conf_lock);
1120
1121#if 0
1122	aprint_error_dev(sc->sc_dev, "%s: tag %#x reg %#x data %#x\n",
1123	    __func__, tag, reg, data);
1124#endif
1125	pq3pci_config_addr_write(pc, tag | reg | PEX_CONFIG_ADDR_EN);
1126	pq3pci_config_data_write(pc, data);
1127
1128	mutex_spin_exit(sc->sc_conf_lock);
1129}
1130
1131#ifdef PCI_NETBSD_CONFIGURE
1132static int
1133pq3pci_conf_hook(void *v, int bus, int dev, int func, pcireg_t id)
1134{
1135	struct pq3pci_softc * const sc = v;
1136	if (sc->sc_pcie && bus != 0) {
1137		pcireg_t slot_status = pci_conf_read(&sc->sc_pc, 0, 0x64);
1138		if ((slot_status & __BIT(6+16)) == 0)
1139			return 0;
1140	}
1141	if (!sc->sc_pcie && bus == 0 && dev == 0) {
1142		return PCI_CONF_DEFAULT ^ (PCI_CONF_MAP_IO|PCI_CONF_MAP_MEM|PCI_CONF_MAP_ROM);
1143	}
1144	return PCI_CONF_DEFAULT;
1145}
1146#endif
1147
1148static void
1149pq3pci_msi_group_setup(struct pq3pci_msigroup *msig, u_int group, int ipl)
1150{
1151	char buf[12];
1152	const char (*intr_names)[8] = msi_intr_names[group];
1153
1154	KASSERT(ipl == IPL_VM);
1155	KASSERT(mutex_owned(&pq3pci_msigroups_lock));
1156
1157	msig->msig_group = group;
1158	msig->msig_free_mask = ~0 << (group == 0);
1159	msig->msig_ipl = ipl;
1160	mutex_init(&msig->msig_lock, MUTEX_DEFAULT, ipl);
1161	snprintf(buf, sizeof(buf), "msi %d-%d", group * 32, group * 32 + 31);
1162	msig->msig_ih = intr_establish_xname(msig->msig_group, ipl,
1163	    IST_MSIGROUP, pq3pci_msi_intr, msig, buf);
1164	msig->msig_msir = OPENPIC_BASE + OPENPIC_MSIR(msig->msig_group);
1165	for (u_int i = 0; i < __arraycount(msig->msig_ihands); i++) {
1166		struct pq3pci_msihand * const msih = msig->msig_ihands + i;
1167		msih->msih_ih.ih_class = IH_MSI;
1168		msih->msih_ih.ih_func = pq3pci_msi_spurious_intr;
1169		msih->msih_ih.ih_arg = msih;
1170		msih->msih_group = msig;
1171		evcnt_attach_dynamic(&msih->msih_ev, EVCNT_TYPE_INTR,
1172		    NULL, intr_names[i], "intr");
1173		evcnt_attach_dynamic(&msih->msih_ev_spurious, EVCNT_TYPE_INTR,
1174		    &msih->msih_ev, intr_names[i], "spurious intr");
1175	}
1176	pq3pci_msigroups[group] = msig;
1177}
1178
1179static struct pq3pci_msihand *
1180pq3pci_msi_lookup(pci_intr_handle_t handle)
1181{
1182	const int irq = PIH_IRQ(handle);
1183	KASSERT(irq < 256);
1184	struct pq3pci_msigroup * const msig = pq3pci_msigroups[irq / 32];
1185	KASSERT(msig != NULL);
1186	return &msig->msig_ihands[irq & 31];
1187}
1188
1189static struct pq3pci_msihand *
1190pq3pci_msi_claim(pci_intr_handle_t handle)
1191{
1192	const int irq = PIH_IRQ(handle);
1193	uint32_t irq_mask = __BIT(irq & 31);
1194	KASSERT(irq < 256);
1195	struct pq3pci_msigroup * const msig = pq3pci_msigroups[irq / 32];
1196	KASSERT(msig != NULL);
1197	struct pq3pci_msihand * const msih = &msig->msig_ihands[irq & 31];
1198	mutex_spin_enter(&msig->msig_lock);
1199	msig->msig_free_mask ^= irq_mask;
1200	mutex_spin_exit(&msig->msig_lock);
1201	return msih;
1202}
1203
1204static pci_intr_handle_t
1205pq3pci_msi_alloc_one(int ipl)
1206{
1207	size_t freegroup = 0;
1208	const size_t maplen = __arraycount(pq3pci_msigroups);
1209	uint32_t bitmap[maplen];
1210	pci_intr_handle_t handle;
1211
1212	mutex_spin_enter(&pq3pci_msigroups_lock);
1213	for (u_int i = 0; i < maplen; i++) {
1214		struct pq3pci_msigroup * const msig = pq3pci_msigroups[i];
1215		if (msig == NULL) {
1216			bitmap[i] = 0;
1217			if (freegroup == 0)
1218				freegroup = i + 1;
1219			continue;
1220		}
1221		/*
1222		 * If this msigroup has the wrong IPL or there's nothing
1223		 * free, try the next one.
1224		 */
1225		if (msig->msig_ipl != ipl || msig->msig_free_mask == 0) {
1226			bitmap[i] = 0;
1227			continue;
1228		}
1229
1230		bitmap[i] = msig->msig_free_mask;
1231	}
1232	for (u_int i = 0; i < maplen; i++) {
1233		uint32_t mapbits = bitmap[i];
1234		u_int n = ffs(mapbits);
1235		if (n--) {
1236			handle = PIH_MAKE(i * 32 + n, IST_MSI, 0);
1237			struct pq3pci_msihand * const msih __diagused =
1238			    pq3pci_msi_claim(handle);
1239			KASSERT(msih != NULL);
1240			mutex_spin_exit(&pq3pci_msigroups_lock);
1241			return handle;
1242		}
1243	}
1244
1245	if (freegroup-- == 0) {
1246		mutex_spin_exit(&pq3pci_msigroups_lock);
1247		return 0;
1248	}
1249
1250	struct pq3pci_msigroup * const msig =
1251	    kmem_zalloc(sizeof(*msig), KM_NOSLEEP);
1252	if (msig == NULL) {
1253		mutex_spin_exit(&pq3pci_msigroups_lock);
1254		return 0;
1255	}
1256	pq3pci_msi_group_setup(msig, freegroup, ipl);
1257	u_int n = ffs(msig->msig_free_mask) - 1;
1258	handle = PIH_MAKE(freegroup * 32 + n, IST_MSI, 0);
1259	struct pq3pci_msihand * const msih __diagused =
1260	    pq3pci_msi_claim(handle);
1261	KASSERT(msih != NULL);
1262	mutex_spin_exit(&pq3pci_msigroups_lock);
1263	return handle;
1264}
1265
1266static int
1267pq3pci_msi_alloc_vectors(struct pq3pci_softc *sc,
1268    const struct pci_attach_args *pa, pci_intr_handle_t **ihps, int count)
1269{
1270	pci_intr_handle_t *vectors;
1271	struct pq3pci_msihand * msih;
1272	pcireg_t msictl;
1273	int msioff;
1274
1275	*ihps = NULL;
1276
1277	if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_MSI, &msioff,
1278	    NULL))
1279		return ENODEV;
1280
1281	msictl = pci_conf_read(pa->pa_pc, pa->pa_tag, msioff);
1282	msictl &= ~PCI_MSI_CTL_MSI_ENABLE;
1283	msictl &= ~PCI_MSI_CTL_MME_MASK;
1284	pci_conf_write(pa->pa_pc, pa->pa_tag, msioff, msictl);
1285
1286	const size_t alloc_size = sizeof(*vectors) * count;
1287	vectors = kmem_zalloc(alloc_size, KM_SLEEP);
1288
1289	for (int i = 0; i < count; ++i) {
1290		pci_intr_handle_t handle = pq3pci_msi_alloc_one(IPL_VM);
1291		if (handle == 0) {
1292			for (int j = i - 1; j >= 0; j--) {
1293				msih = pq3pci_msi_claim(vectors[j]);
1294				msih->msih_tag = 0;
1295				msih->msih_msioff = 0;
1296			}
1297			kmem_free(vectors, alloc_size);
1298			return EBUSY;
1299		}
1300		vectors[i] = handle;
1301
1302		msih = pq3pci_msi_lookup(handle);
1303		msih->msih_tag = pa->pa_tag;
1304		msih->msih_msioff = msioff;
1305	}
1306
1307	*ihps = vectors;
1308	return 0;
1309}
1310
1311static void
1312pq3pci_msi_free_vectors(struct pq3pci_softc *sc, pci_intr_handle_t *ihp,
1313    int count)
1314{
1315
1316	KASSERT(count > 0);
1317
1318	for (int i = 0; i < count; ++i) {
1319		struct pq3pci_msihand * const msih __diagused =
1320		    pq3pci_msi_claim(ihp[i]);
1321		KASSERT(msih != NULL);
1322	}
1323	kmem_free(ihp, sizeof(*ihp) * count);
1324}
1325
1326static struct pq3pci_intrsource *
1327pq3pci_intr_source_lookup(struct pq3pci_softc *sc, pci_intr_handle_t handle)
1328{
1329	struct pq3pci_intrsource *pis;
1330	mutex_spin_enter(&pq3pci_intrsources_lock);
1331	SIMPLEQ_FOREACH(pis, &pq3pci_intrsources, pis_link) {
1332		if (pis->pis_handle == handle) {
1333			mutex_spin_exit(&pq3pci_intrsources_lock);
1334			return pis;
1335		}
1336	}
1337	pis = kmem_zalloc(sizeof(*pis), KM_NOSLEEP);
1338	if (pis != NULL)
1339		pq3pci_intr_source_setup(sc, pis, handle);
1340	mutex_spin_exit(&pq3pci_intrsources_lock);
1341	return pis;
1342}
1343
1344static pci_intr_handle_t
1345pq3pci_intr_handle_lookup(struct pq3pci_softc *sc,
1346    const struct pci_attach_args *pa)
1347{
1348	prop_dictionary_t entry;
1349
1350#ifndef PQ3PCI_INTR_MAP_NO_USE_MSI
1351	if (sc->sc_pcie) do {
1352		pcireg_t msictl;
1353		int msioff;
1354		if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_MSI,
1355					&msioff, NULL))
1356			break;
1357		msictl = pci_conf_read(pa->pa_pc, pa->pa_tag, msioff);
1358		msictl &= ~PCI_MSI_CTL_MSI_ENABLE;
1359		msictl &= ~PCI_MSI_CTL_MME_MASK;
1360		pci_conf_write(pa->pa_pc, pa->pa_tag, msioff, msictl);
1361		pci_intr_handle_t handle = pq3pci_msi_alloc_one(IPL_VM);
1362		struct pq3pci_msihand * const msih = pq3pci_msi_lookup(handle);
1363		msih->msih_tag = pa->pa_tag;
1364		msih->msih_msioff = msioff;
1365		return handle;
1366	} while (false);
1367#endif
1368
1369	if (sc->sc_intrmask == 0) {
1370		entry = prop_dictionary_get(sc->sc_intrmap, "000000");
1371	} else {
1372		char prop_name[8];
1373		u_int intrinc = __LOWEST_SET_BIT(sc->sc_intrmask);
1374		pcitag_t tag = (pa->pa_intrpin - PCI_INTERRUPT_PIN_A) * intrinc;
1375
1376		snprintf(prop_name, sizeof(prop_name), "%06x",
1377		    tag & sc->sc_intrmask);
1378
1379#if 0
1380		printf("%s: %#x %#x %u (%u) -> %#x & %#x -> %#x <%s>\n",
1381		    __func__, pa->pa_tag, pa->pa_intrtag, pa->pa_intrpin, pa->pa_rawintrpin,
1382		    tag, sc->sc_intrmask, tag & sc->sc_intrmask, prop_name);
1383#endif
1384
1385		entry = prop_dictionary_get(sc->sc_intrmap, prop_name);
1386	}
1387	KASSERT(entry != NULL);
1388	KASSERT(prop_object_type(entry) == PROP_TYPE_DICTIONARY);
1389
1390	prop_number_t pn_irq = prop_dictionary_get(entry, "interrupt");
1391	KASSERT(pn_irq != NULL);
1392	KASSERT(prop_object_type(pn_irq) == PROP_TYPE_NUMBER);
1393	int irq = prop_number_unsigned_integer_value(pn_irq);
1394	prop_number_t pn_ist = prop_dictionary_get(entry, "type");
1395	KASSERT(pn_ist != NULL);
1396	KASSERT(prop_object_type(pn_ist) == PROP_TYPE_NUMBER);
1397	int ist = prop_number_unsigned_integer_value(pn_ist);
1398
1399	return PIH_MAKE(irq, ist, 0);
1400}
1401
1402static int
1403pq3pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *handlep)
1404{
1405	struct pq3pci_softc * const sc = pa->pa_pc->pc_intr_v;
1406
1407	if (pa->pa_intrpin == PCI_INTERRUPT_PIN_NONE)
1408		return ENOENT;
1409
1410	*handlep = pq3pci_intr_handle_lookup(sc, pa);
1411
1412	return 0;
1413}
1414
1415static const char *
1416pq3pci_intr_string(void *v, pci_intr_handle_t handle, char *buf, size_t len)
1417{
1418	if (PIH_IST(handle) == IST_MSI) {
1419		const char (*intr_names)[8] = msi_intr_names[0];
1420		strlcpy(buf, intr_names[PIH_IRQ(handle)], len);
1421		return buf;
1422	}
1423
1424	return intr_string(PIH_IRQ(handle), PIH_IST(handle), buf, len);
1425}
1426
1427static const struct evcnt *
1428pq3pci_intr_evcnt(void *v, pci_intr_handle_t handle)
1429{
1430	struct pq3pci_softc * const sc = v;
1431	if (PIH_IST(handle) == IST_MSI) {
1432		struct pq3pci_msihand * const msih = pq3pci_msi_lookup(handle);
1433
1434		KASSERT(msih != NULL);
1435
1436		return &msih->msih_ev;
1437	}
1438	struct pq3pci_intrsource * const pis =
1439	    pq3pci_intr_source_lookup(sc, handle);
1440	if (pis != NULL)
1441		return &pis->pis_ev;
1442	return NULL;
1443}
1444
1445static void *
1446pq3pci_intr_establish(void *v, pci_intr_handle_t handle, int ipl,
1447	int (*func)(void *), void *arg, const char *xname)
1448{
1449	struct pq3pci_softc * const sc = v;
1450	const int ist = PIH_IST(handle);
1451
1452	if (ist == IST_MSI) {
1453		pci_chipset_tag_t pc = &sc->sc_pc;
1454		struct pq3pci_msihand * const msih = pq3pci_msi_lookup(handle);
1455		pcireg_t cmdsts, msictl;
1456
1457		if (msih == NULL)
1458			return NULL;
1459
1460		struct pq3pci_msigroup * const msig = msih->msih_group;
1461		const pcitag_t tag = msih->msih_tag;
1462
1463		mutex_spin_enter(&msig->msig_lock);
1464		msih->msih_ih.ih_class = IH_MSI;
1465		msih->msih_ih.ih_arg = arg;
1466		msih->msih_ih.ih_func = func;
1467		msih->msih_ih.ih_sc = sc;
1468
1469		int off = msih->msih_msioff;
1470		msictl = pci_conf_read(pc, tag, off);
1471
1472		/*
1473		 * The PCSRBAR has already been setup as a 1:1 BAR so we point
1474		 * MSIs at the MSII register in the OpenPIC.
1475		 */
1476		off += 4;
1477		pci_conf_write(pc, tag, off,
1478		    sc->sc_bst->pbs_offset + OPENPIC_BASE + OPENPIC_MSIIR);
1479
1480		/*
1481		 * Upper address is going to be 0.
1482		 */
1483		if (msictl & PCI_MSI_CTL_64BIT_ADDR) {
1484			off += 4;
1485			pci_conf_write(pc, tag, off, 0);
1486		}
1487
1488		/*
1489		 * Set the magic value.  Since PCI writes this to the least
1490		 * significant byte of AD[31:0], let's hope the bridge byte
1491		 * swaps to so it's the most significant bytes or nothing is
1492		 * going to happen.
1493		 */
1494		off += 4;
1495		pci_conf_write(pc, tag, off, PIH_IRQ(handle));
1496
1497		/*
1498		 * Should the driver do this?  How would it know to do it?
1499		 */
1500		if (msictl & PCI_MSI_CTL_PERVEC_MASK) {
1501			off += 4;
1502			pci_conf_write(pc, tag, off, 0);
1503		}
1504
1505		/*
1506		 * Let's make sure he won't raise any INTx.  Technically
1507		 * setting MSI enable will prevent that as well but might
1508		 * as well be as safe as possible.
1509		 */
1510		cmdsts = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
1511		cmdsts |= PCI_COMMAND_INTERRUPT_DISABLE;
1512		pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, cmdsts);
1513
1514#if 1
1515		/*
1516		 * Now we can enable the MSI
1517		 */
1518		msictl |= PCI_MSI_CTL_MSI_ENABLE;
1519		pci_conf_write(pc, tag, msih->msih_msioff, msictl);
1520#endif
1521
1522		mutex_spin_exit(&msig->msig_lock);
1523
1524		return msih;
1525	}
1526
1527	struct pq3pci_intrsource * const pis =
1528	    pq3pci_intr_source_lookup(sc, handle);
1529	if (pis == NULL)
1530		return NULL;
1531
1532	struct pq3pci_intrhand * const pih =
1533	    kmem_zalloc(sizeof(*pih), KM_SLEEP);
1534	pih->pih_ih.ih_class = IH_INTX;
1535	pih->pih_ih.ih_func = func;
1536	pih->pih_ih.ih_arg = arg;
1537	pih->pih_ih.ih_sc = sc;
1538	pih->pih_ipl = ipl;
1539	pih->pih_source = pis;
1540
1541	mutex_spin_enter(&pis->pis_lock);
1542	SIMPLEQ_INSERT_TAIL(&pis->pis_ihands, pih, pih_link);
1543	mutex_spin_exit(&pis->pis_lock);
1544
1545	return pih;
1546}
1547
1548static void
1549pq3pci_intr_disestablish(void *v, void *ih)
1550{
1551	struct pq3pci_genihand * const gih = ih;
1552
1553	if (gih->ih_class == IH_INTX) {
1554		struct pq3pci_intrhand * const pih = ih;
1555		struct pq3pci_intrsource * const pis = pih->pih_source;
1556
1557		mutex_spin_enter(&pis->pis_lock);
1558		SIMPLEQ_REMOVE(&pis->pis_ihands, pih, pq3pci_intrhand, pih_link);
1559		mutex_spin_exit(&pis->pis_lock);
1560
1561		kmem_free(pih, sizeof(*pih));
1562		return;
1563	}
1564
1565	struct pq3pci_msihand * const msih = ih;
1566	struct pq3pci_msigroup * const msig = msih->msih_group;
1567	struct genppc_pci_chipset * const pc = &msih->msih_ih.ih_sc->sc_pc;
1568	const pcitag_t tag = msih->msih_tag;
1569
1570	mutex_spin_enter(&msig->msig_lock);
1571
1572	/*
1573	 * disable the MSI
1574	 */
1575	pcireg_t msictl = pci_conf_read(pc, tag, msih->msih_msioff);
1576	msictl &= ~PCI_MSI_CTL_MSI_ENABLE;
1577	pci_conf_write(pc, tag, msih->msih_msioff, msictl);
1578
1579	msih->msih_ih.ih_func = pq3pci_msi_spurious_intr;
1580	msih->msih_ih.ih_arg = msig;
1581	msih->msih_ih.ih_sc = NULL;
1582	msih->msih_tag = 0;
1583	msih->msih_msioff = 0;
1584	mutex_spin_exit(&msig->msig_lock);
1585}
1586
1587static pci_intr_type_t
1588pq3pci_intr_type(void *v, pci_intr_handle_t handle)
1589{
1590	const int ist = PIH_IST(handle);
1591
1592	if (ist == IST_MSI)
1593		return PCI_INTR_TYPE_MSI;
1594	return PCI_INTR_TYPE_INTX;
1595}
1596
1597static int
1598pq3pci_intr_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps,
1599    int *counts, pci_intr_type_t max_type)
1600{
1601	int cnt[PCI_INTR_TYPE_SIZE];
1602	int error;
1603
1604	memset(cnt, 0, sizeof(cnt));
1605	if (counts == NULL) {
1606		/* simple pattern */
1607		cnt[PCI_INTR_TYPE_INTX] = 1;
1608		cnt[PCI_INTR_TYPE_MSI] = 1;
1609	} else {
1610		switch (max_type) {
1611		case PCI_INTR_TYPE_MSIX:
1612			cnt[PCI_INTR_TYPE_MSIX] = counts[PCI_INTR_TYPE_MSIX];
1613			/*FALLTHROUGH*/
1614		case PCI_INTR_TYPE_MSI:
1615			cnt[PCI_INTR_TYPE_MSI] = counts[PCI_INTR_TYPE_MSI];
1616			/*FALLTHROUGH*/
1617		case PCI_INTR_TYPE_INTX:
1618			cnt[PCI_INTR_TYPE_INTX] = counts[PCI_INTR_TYPE_INTX];
1619			break;
1620		default:
1621			return EINVAL;
1622		}
1623	}
1624
1625	if (counts != NULL)
1626		memset(counts, 0, sizeof(counts[0]) * (max_type + 1));
1627	error = EINVAL;
1628
1629	/* try MSI-X */
1630	if (cnt[PCI_INTR_TYPE_MSIX] == -1) /* use hardware max */
1631		cnt[PCI_INTR_TYPE_MSIX] = pci_msix_count(pa->pa_pc, pa->pa_tag);
1632	if (cnt[PCI_INTR_TYPE_MSIX] > 0) {
1633		error = pci_msix_alloc_exact(pa, ihps, cnt[PCI_INTR_TYPE_MSIX]);
1634		if (error == 0) {
1635			KASSERTMSG(counts != NULL,
1636			    "If MSI-X is used, counts must not be NULL.");
1637			counts[PCI_INTR_TYPE_MSIX] = cnt[PCI_INTR_TYPE_MSIX];
1638			goto out;
1639		}
1640	}
1641
1642	/* try MSI */
1643	if (cnt[PCI_INTR_TYPE_MSI] == -1) /* use hardware max */
1644		cnt[PCI_INTR_TYPE_MSI] = pci_msi_count(pa->pa_pc, pa->pa_tag);
1645	if (cnt[PCI_INTR_TYPE_MSI] > 0) {
1646		error = pci_msi_alloc_exact(pa, ihps, cnt[PCI_INTR_TYPE_MSI]);
1647		if (error == 0) {
1648			if (counts != NULL) {
1649				counts[PCI_INTR_TYPE_MSI] =
1650				    cnt[PCI_INTR_TYPE_MSI];
1651			}
1652			goto out;
1653		}
1654	}
1655
1656	/* try INTx */
1657	if (cnt[PCI_INTR_TYPE_INTX] > 0) {
1658		error = pci_intx_alloc(pa, ihps);
1659		if (error == 0 && counts != NULL) {
1660			counts[PCI_INTR_TYPE_INTX] = 1;
1661		}
1662	}
1663
1664 out:
1665	return error;
1666}
1667
1668static void
1669pq3pci_intr_release(void *v, pci_intr_handle_t *ihps, int count)
1670{
1671
1672	if (ihps == NULL)
1673		return;
1674
1675	const int ist = PIH_IST(*ihps);
1676	if (ist == IST_MSI)
1677		pq3pci_msi_free_vectors(v, ihps, count);
1678	else
1679		genppc_pci_intr_release(v, ihps, count);
1680}
1681
1682static void
1683pq3pci_conf_interrupt(void *v, int bus, int dev, int pin, int swiz, int *iline)
1684{
1685}
1686
1687/* experimental MSI support */
1688
1689/*
1690 * This function is used by device drivers like pci_intr_map().
1691 *
1692 * "ihps" is the array of vector numbers which MSI used instead of IRQ number.
1693 * "count" must be power of 2.
1694 * "count" can decrease if struct intrsource cannot be allocated.
1695 * if count == 0, return non-zero value.
1696 */
1697static int
1698pq3pci_msi_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps,
1699    int *count, bool exact)
1700{
1701	struct pq3pci_softc * const sc = pa->pa_pc->pc_msi_v;
1702	int hw_max;
1703	int error;
1704
1705	if (*count < 1)
1706		return EINVAL;
1707	if (((*count - 1) & *count) != 0)
1708		return EINVAL;
1709
1710	hw_max = pci_msi_count(pa->pa_pc, pa->pa_tag);
1711	if (hw_max == 0)
1712		return ENODEV;
1713
1714	if (*count > hw_max)
1715		*count = hw_max;
1716
1717	*ihps = NULL;
1718	for (; *count > 0; (*count) >>= 1) {
1719		error = pq3pci_msi_alloc_vectors(sc, pa, ihps, *count);
1720		if (error == 0)
1721			break;
1722		if (exact)
1723			return error;
1724	}
1725	if (*ihps == NULL)
1726		return ENXIO;
1727
1728	return 0;
1729}
1730
1731static pci_chipset_tag_t
1732pq3pci_pci_chipset_init(struct pq3pci_softc *sc)
1733{
1734	struct genppc_pci_chipset * const pc = &sc->sc_pc;
1735
1736	pc->pc_conf_v = sc;
1737	pc->pc_attach_hook = pq3pci_attach_hook;
1738	pc->pc_bus_maxdevs = pq3pci_bus_maxdevs;
1739	pc->pc_make_tag = pq3pci_make_tag;
1740	pc->pc_conf_read = pq3pci_conf_read;
1741	pc->pc_conf_write = pq3pci_conf_write;
1742#ifdef PCI_NETBSD_CONFIGURE
1743	pc->pc_conf_hook = pq3pci_conf_hook;
1744#endif
1745
1746	pc->pc_intr_v = sc;
1747	pc->pc_intr_map = pq3pci_intr_map;
1748	pc->pc_intr_string = pq3pci_intr_string;
1749	pc->pc_intr_evcnt = pq3pci_intr_evcnt;
1750	pc->pc_intr_establish = pq3pci_intr_establish;
1751	pc->pc_intr_disestablish = pq3pci_intr_disestablish;
1752	pc->pc_intr_type = pq3pci_intr_type;
1753	pc->pc_intr_alloc = pq3pci_intr_alloc;
1754	pc->pc_intr_release = pq3pci_intr_release;
1755	pc->pc_intr_setattr = genppc_pci_intr_setattr;
1756	pc->pc_intx_alloc = genppc_pci_intx_alloc;
1757
1758	pc->pc_msi_v = sc;
1759	pc->pc_msi_alloc = pq3pci_msi_alloc;
1760
1761	pc->pc_msix_v = sc;
1762	genppc_pci_chipset_msix_init(pc);
1763
1764	pc->pc_conf_interrupt = pq3pci_conf_interrupt;
1765	pc->pc_decompose_tag = pq3pci_decompose_tag;
1766
1767	/*
1768	 * This is a horrible kludge but it makes life easier.
1769	 */
1770	pc->pc_addr = (void *)(sc->sc_bsh + PEX_CONFIG_ADDR);
1771	pc->pc_data = (void *)(sc->sc_bsh + PEX_CONFIG_DATA);
1772	pc->pc_bus = 0;
1773	pc->pc_memt = &sc->sc_pci_mem_bst.bs_tag;
1774	pc->pc_iot = &sc->sc_pci_io_bst.bs_tag;
1775
1776	SIMPLEQ_INIT(&pc->pc_pbi);
1777
1778	return pc;
1779}
1780