| @@ -93,27 +93,27 @@ | | | @@ -93,27 +93,27 @@ |
93 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 93 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
94 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 94 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
95 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 95 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
96 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 96 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
97 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 97 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
98 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 98 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
99 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 99 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
100 | * SUCH DAMAGE. | | 100 | * SUCH DAMAGE. |
101 | * | | 101 | * |
102 | * @(#)isa.c 7.2 (Berkeley) 5/13/91 | | 102 | * @(#)isa.c 7.2 (Berkeley) 5/13/91 |
103 | */ | | 103 | */ |
104 | | | 104 | |
105 | #include <sys/cdefs.h> | | 105 | #include <sys/cdefs.h> |
106 | __KERNEL_RCSID(0, "$NetBSD: pintr.c,v 1.16 2020/05/15 07:42:58 jdolecek Exp $"); | | 106 | __KERNEL_RCSID(0, "$NetBSD: pintr.c,v 1.17 2020/05/23 14:51:19 jdolecek Exp $"); |
107 | | | 107 | |
108 | #include "opt_multiprocessor.h" | | 108 | #include "opt_multiprocessor.h" |
109 | #include "opt_xen.h" | | 109 | #include "opt_xen.h" |
110 | #include "isa.h" | | 110 | #include "isa.h" |
111 | #include "pci.h" | | 111 | #include "pci.h" |
112 | | | 112 | |
113 | #include <sys/param.h> | | 113 | #include <sys/param.h> |
114 | #include <sys/systm.h> | | 114 | #include <sys/systm.h> |
115 | #include <sys/kernel.h> | | 115 | #include <sys/kernel.h> |
116 | #include <sys/syslog.h> | | 116 | #include <sys/syslog.h> |
117 | #include <sys/device.h> | | 117 | #include <sys/device.h> |
118 | #include <sys/proc.h> | | 118 | #include <sys/proc.h> |
119 | #include <sys/errno.h> | | 119 | #include <sys/errno.h> |
| @@ -163,67 +163,68 @@ short irq2port[NR_EVENT_CHANNELS] = {0}; | | | @@ -163,67 +163,68 @@ short irq2port[NR_EVENT_CHANNELS] = {0}; |
163 | #endif | | 163 | #endif |
164 | | | 164 | |
165 | #if defined(DOM0OPS) || NPCI > 0 | | 165 | #if defined(DOM0OPS) || NPCI > 0 |
166 | /* | | 166 | /* |
167 | * This function doesn't "allocate" anything. It merely translates our | | 167 | * This function doesn't "allocate" anything. It merely translates our |
168 | * understanding of PIC to the XEN 'gsi' namespace. In the case of | | 168 | * understanding of PIC to the XEN 'gsi' namespace. In the case of |
169 | * MSIs, pirq == irq. In the case of everything else, the hypervisor | | 169 | * MSIs, pirq == irq. In the case of everything else, the hypervisor |
170 | * doesn't really care, so we just use the native conventions that | | 170 | * doesn't really care, so we just use the native conventions that |
171 | * have been setup during boot by mpbios.c/mpacpi.c | | 171 | * have been setup during boot by mpbios.c/mpacpi.c |
172 | */ | | 172 | */ |
173 | int | | 173 | int |
174 | xen_pic_to_gsi(struct pic *pic, int pin) | | 174 | xen_pic_to_gsi(struct pic *pic, int pin) |
175 | { | | 175 | { |
176 | struct physdev_map_pirq map_irq; | | | |
177 | int ret; | | 176 | int ret; |
178 | int gsi; | | 177 | int gsi; |
179 | | | 178 | |
180 | KASSERT(pic != NULL); | | 179 | KASSERT(pic != NULL); |
181 | | | 180 | |
182 | /* | | 181 | /* |
183 | * We assume that mpbios/mpacpi have done the right thing. | | 182 | * We assume that mpbios/mpacpi have done the right thing. |
184 | * If so, legacy_irq should identity map correctly to gsi. | | 183 | * If so, legacy_irq should identity map correctly to gsi. |
185 | */ | | 184 | */ |
186 | gsi = pic->pic_vecbase + pin; | | 185 | gsi = pic->pic_vecbase + pin; |
187 | KASSERT(gsi < NR_EVENT_CHANNELS); | | 186 | KASSERT(gsi < NR_EVENT_CHANNELS); |
188 | | | 187 | |
189 | switch (pic->pic_type) { | | 188 | switch (pic->pic_type) { |
190 | case PIC_I8259: | | 189 | case PIC_I8259: |
191 | KASSERT(gsi < 16); | | 190 | KASSERT(gsi < 16); |
192 | /* FALLTHROUGH */ | | 191 | /* FALLTHROUGH */ |
193 | case PIC_IOAPIC: | | 192 | case PIC_IOAPIC: |
194 | { | | 193 | { |
195 | KASSERT(gsi < 255); | | 194 | KASSERT(gsi < 255); |
196 | | | 195 | |
197 | if (irq2port[gsi] != 0) { | | 196 | if (irq2port[gsi] != 0) { |
198 | /* Already mapped the shared interrupt */ | | 197 | /* Already mapped the shared interrupt */ |
199 | break; | | 198 | break; |
200 | } | | 199 | } |
201 | | | 200 | |
202 | memset(&map_irq, 0, sizeof(map_irq)); | | 201 | struct physdev_irq irq_op; |
203 | map_irq.domid = DOMID_SELF; | | 202 | memset(&irq_op, 0, sizeof(irq_op)); |
204 | map_irq.type = MAP_PIRQ_TYPE_GSI; | | 203 | irq_op.irq = gsi; |
205 | map_irq.index = pin; | | 204 | ret = HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, |
206 | map_irq.pirq = gsi; | | 205 | &irq_op); |
207 | ret = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); | | 206 | if (ret < 0) { |
208 | if (ret != 0) | | 207 | panic("physdev_op(PHYSDEVOP_alloc_irq_vector) %d" |
209 | panic("physdev_op(PHYSDEVOP_map_pirq) GSI fail %d", | | 208 | " fail %d", gsi, ret); |
210 | ret); | | 209 | } |
| | | 210 | KASSERT(irq_op.vector == gsi); |
211 | break; | | 211 | break; |
212 | } | | 212 | } |
213 | case PIC_MSI: | | 213 | case PIC_MSI: |
214 | case PIC_MSIX: | | 214 | case PIC_MSIX: |
215 | #ifdef __HAVE_PCI_MSI_MSIX | | 215 | #ifdef __HAVE_PCI_MSI_MSIX |
216 | { | | 216 | { |
| | | 217 | struct physdev_map_pirq map_irq; |
217 | const struct msipic_pci_info *i = msipic_get_pci_info(pic); | | 218 | const struct msipic_pci_info *i = msipic_get_pci_info(pic); |
218 | | | 219 | |
219 | memset(&map_irq, 0, sizeof(map_irq)); | | 220 | memset(&map_irq, 0, sizeof(map_irq)); |
220 | map_irq.domid = DOMID_SELF; | | 221 | map_irq.domid = DOMID_SELF; |
221 | map_irq.type = MAP_PIRQ_TYPE_MSI_SEG; | | 222 | map_irq.type = MAP_PIRQ_TYPE_MSI_SEG; |
222 | map_irq.index = -1; | | 223 | map_irq.index = -1; |
223 | map_irq.pirq = -1; | | 224 | map_irq.pirq = -1; |
224 | map_irq.bus = i->mp_bus; | | 225 | map_irq.bus = i->mp_bus; |
225 | map_irq.devfn = (i->mp_dev << 3) | i->mp_fun; | | 226 | map_irq.devfn = (i->mp_dev << 3) | i->mp_fun; |
226 | KASSERT(i->mp_veccnt > 0); | | 227 | KASSERT(i->mp_veccnt > 0); |
227 | map_irq.entry_nr = i->mp_veccnt; | | 228 | map_irq.entry_nr = i->mp_veccnt; |
228 | if (pic->pic_type == PIC_MSI && i->mp_veccnt > 1) { | | 229 | if (pic->pic_type == PIC_MSI && i->mp_veccnt > 1) { |
229 | map_irq.type = MAP_PIRQ_TYPE_MULTI_MSI; | | 230 | map_irq.type = MAP_PIRQ_TYPE_MULTI_MSI; |