pci_irq.c (bf21cd93) pci_irq.c (4c87aefe)
1/*-
1/*-
2 * Copyright (c) 2014 Advanced Computing Technologies LLC
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2014 Hudson River Trading LLC
3 * Written by: John H. Baldwin <jhb@FreeBSD.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.

--- 11 unchanged lines hidden (view full) ---

22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28
29#include <sys/cdefs.h>
5 * Written by: John H. Baldwin <jhb@FreeBSD.org>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.

--- 11 unchanged lines hidden (view full) ---

24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30
31#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/usr.sbin/bhyve/pci_irq.c 266125 2014-05-15 14:16:55Z jhb $");
32__FBSDID("$FreeBSD$");
31
32#include <sys/param.h>
33#include <machine/vmm.h>
34
35#include <assert.h>
36#include <pthread.h>
37#include <stdbool.h>
38#include <stdio.h>

--- 71 unchanged lines hidden (view full) ---

110 }
111 pthread_mutex_unlock(&pirq->lock);
112}
113
114void
115pci_irq_reserve(int irq)
116{
117
33
34#include <sys/param.h>
35#include <machine/vmm.h>
36
37#include <assert.h>
38#include <pthread.h>
39#include <stdbool.h>
40#include <stdio.h>

--- 71 unchanged lines hidden (view full) ---

112 }
113 pthread_mutex_unlock(&pirq->lock);
114}
115
116void
117pci_irq_reserve(int irq)
118{
119
118 assert(irq < nitems(irq_counts));
120 assert(irq >= 0 && irq < nitems(irq_counts));
119 assert(pirq_cold);
120 assert(irq_counts[irq] == 0 || irq_counts[irq] == IRQ_DISABLED);
121 irq_counts[irq] = IRQ_DISABLED;
122}
123
124void
125pci_irq_use(int irq)
126{
127
121 assert(pirq_cold);
122 assert(irq_counts[irq] == 0 || irq_counts[irq] == IRQ_DISABLED);
123 irq_counts[irq] = IRQ_DISABLED;
124}
125
126void
127pci_irq_use(int irq)
128{
129
128 assert(irq < nitems(irq_counts));
130 assert(irq >= 0 && irq < nitems(irq_counts));
129 assert(pirq_cold);
131 assert(pirq_cold);
130 if (irq_counts[irq] != IRQ_DISABLED)
131 irq_counts[irq]++;
132 assert(irq_counts[irq] != IRQ_DISABLED);
133 irq_counts[irq]++;
132}
133
134void
135pci_irq_init(struct vmctx *ctx)
136{
137 int i;
138
139 for (i = 0; i < nitems(pirqs); i++) {

--- 48 unchanged lines hidden (view full) ---

188 return;
189 }
190 pthread_mutex_unlock(&pirq->lock);
191 }
192 vm_ioapic_deassert_irq(pi->pi_vmctx, pi->pi_lintr.ioapic_irq);
193}
194
195int
134}
135
136void
137pci_irq_init(struct vmctx *ctx)
138{
139 int i;
140
141 for (i = 0; i < nitems(pirqs); i++) {

--- 48 unchanged lines hidden (view full) ---

190 return;
191 }
192 pthread_mutex_unlock(&pirq->lock);
193 }
194 vm_ioapic_deassert_irq(pi->pi_vmctx, pi->pi_lintr.ioapic_irq);
195}
196
197int
196pirq_alloc_pin(struct vmctx *ctx)
198pirq_alloc_pin(struct pci_devinst *pi)
197{
199{
200 struct vmctx *ctx = pi->pi_vmctx;
198 int best_count, best_irq, best_pin, irq, pin;
199
201 int best_count, best_irq, best_pin, irq, pin;
202
200 pirq_cold = 1;
203 pirq_cold = 0;
201
204
202 /* First, find the least-used PIRQ pin. */
203 best_pin = 0;
204 best_count = pirqs[0].use_count;
205 for (pin = 1; pin < nitems(pirqs); pin++) {
206 if (pirqs[pin].use_count < best_count) {
207 best_pin = pin;
208 best_count = pirqs[pin].use_count;
205 if (lpc_bootrom()) {
206 /* For external bootrom use fixed mapping. */
207 best_pin = (4 + pi->pi_slot + pi->pi_lintr.pin) % 8;
208 } else {
209 /* Find the least-used PIRQ pin. */
210 best_pin = 0;
211 best_count = pirqs[0].use_count;
212 for (pin = 1; pin < nitems(pirqs); pin++) {
213 if (pirqs[pin].use_count < best_count) {
214 best_pin = pin;
215 best_count = pirqs[pin].use_count;
216 }
209 }
210 }
211 pirqs[best_pin].use_count++;
212
213 /* Second, route this pin to an IRQ. */
214 if (pirqs[best_pin].reg == PIRQ_DIS) {
215 best_irq = -1;
216 best_count = 0;
217 for (irq = 0; irq < nitems(irq_counts); irq++) {
218 if (irq_counts[irq] == IRQ_DISABLED)
219 continue;
220 if (best_irq == -1 || irq_counts[irq] < best_count) {
221 best_irq = irq;
222 best_count = irq_counts[irq];
223 }
224 }
217 }
218 }
219 pirqs[best_pin].use_count++;
220
221 /* Second, route this pin to an IRQ. */
222 if (pirqs[best_pin].reg == PIRQ_DIS) {
223 best_irq = -1;
224 best_count = 0;
225 for (irq = 0; irq < nitems(irq_counts); irq++) {
226 if (irq_counts[irq] == IRQ_DISABLED)
227 continue;
228 if (best_irq == -1 || irq_counts[irq] < best_count) {
229 best_irq = irq;
230 best_count = irq_counts[irq];
231 }
232 }
225 assert(best_irq != 0);
233 assert(best_irq >= 0);
226 irq_counts[best_irq]++;
227 pirqs[best_pin].reg = best_irq;
228 vm_isa_set_irq_trigger(ctx, best_irq, LEVEL_TRIGGER);
229 }
230
231 return (best_pin + 1);
232}
233
234int
235pirq_irq(int pin)
236{
234 irq_counts[best_irq]++;
235 pirqs[best_pin].reg = best_irq;
236 vm_isa_set_irq_trigger(ctx, best_irq, LEVEL_TRIGGER);
237 }
238
239 return (best_pin + 1);
240}
241
242int
243pirq_irq(int pin)
244{
237
238 if (pin == -1)
239 return (255);
240 assert(pin > 0 && pin <= nitems(pirqs));
241 return (pirqs[pin - 1].reg & PIRQ_IRQ);
242}
243
244/* XXX: Generate $PIR table. */
245
245 assert(pin > 0 && pin <= nitems(pirqs));
246 return (pirqs[pin - 1].reg & PIRQ_IRQ);
247}
248
249/* XXX: Generate $PIR table. */
250
246#ifdef __FreeBSD__
247static void
248pirq_dsdt(void)
249{
250 char *irq_prs, *old;
251 int irq, pin;
252
253 irq_prs = NULL;
254 for (irq = 0; irq < nitems(irq_counts); irq++) {

--- 88 unchanged lines hidden (view full) ---

343 dsdt_line(" FindSetRightBit (SIR%c, Local0)", 'A' + pin);
344 dsdt_line(" Store (Decrement (Local0), PIR%c)", 'A' + pin);
345 dsdt_line(" }");
346 dsdt_line("}");
347 }
348 free(irq_prs);
349}
350LPC_DSDT(pirq_dsdt);
251static void
252pirq_dsdt(void)
253{
254 char *irq_prs, *old;
255 int irq, pin;
256
257 irq_prs = NULL;
258 for (irq = 0; irq < nitems(irq_counts); irq++) {

--- 88 unchanged lines hidden (view full) ---

347 dsdt_line(" FindSetRightBit (SIR%c, Local0)", 'A' + pin);
348 dsdt_line(" Store (Decrement (Local0), PIR%c)", 'A' + pin);
349 dsdt_line(" }");
350 dsdt_line("}");
351 }
352 free(irq_prs);
353}
354LPC_DSDT(pirq_dsdt);
351#endif