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 | |