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