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