pci_emul.c (268953) | pci_emul.c (268972) |
---|---|
1/*- 2 * Copyright (c) 2011 NetApp, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * | 1/*- 2 * Copyright (c) 2011 NetApp, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * |
26 * $FreeBSD: stable/10/usr.sbin/bhyve/pci_emul.c 268953 2014-07-21 19:08:02Z jhb $ | 26 * $FreeBSD: stable/10/usr.sbin/bhyve/pci_emul.c 268972 2014-07-22 03:14:37Z jhb $ |
27 */ 28 29#include <sys/cdefs.h> | 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: stable/10/usr.sbin/bhyve/pci_emul.c 268953 2014-07-21 19:08:02Z jhb $"); | 30__FBSDID("$FreeBSD: stable/10/usr.sbin/bhyve/pci_emul.c 268972 2014-07-22 03:14:37Z jhb $"); |
31 32#include <sys/param.h> 33#include <sys/linker_set.h> 34#include <sys/errno.h> 35 36#include <ctype.h> 37#include <pthread.h> 38#include <stdio.h> --- 7 unchanged lines hidden (view full) --- 46#include <vmmapi.h> 47 48#include "acpi.h" 49#include "bhyverun.h" 50#include "inout.h" 51#include "ioapic.h" 52#include "mem.h" 53#include "pci_emul.h" | 31 32#include <sys/param.h> 33#include <sys/linker_set.h> 34#include <sys/errno.h> 35 36#include <ctype.h> 37#include <pthread.h> 38#include <stdio.h> --- 7 unchanged lines hidden (view full) --- 46#include <vmmapi.h> 47 48#include "acpi.h" 49#include "bhyverun.h" 50#include "inout.h" 51#include "ioapic.h" 52#include "mem.h" 53#include "pci_emul.h" |
54#include "pci_irq.h" |
|
54#include "pci_lpc.h" 55 56#define CONF1_ADDR_PORT 0x0cf8 57#define CONF1_DATA_PORT 0x0cfc 58 59#define CONF1_ENABLE 0x80000000ul 60 61#define CFGWRITE(pi,off,val,b) \ --- 14 unchanged lines hidden (view full) --- 76struct funcinfo { 77 char *fi_name; 78 char *fi_param; 79 struct pci_devinst *fi_devi; 80}; 81 82struct intxinfo { 83 int ii_count; | 55#include "pci_lpc.h" 56 57#define CONF1_ADDR_PORT 0x0cf8 58#define CONF1_DATA_PORT 0x0cfc 59 60#define CONF1_ENABLE 0x80000000ul 61 62#define CFGWRITE(pi,off,val,b) \ --- 14 unchanged lines hidden (view full) --- 77struct funcinfo { 78 char *fi_name; 79 char *fi_param; 80 struct pci_devinst *fi_devi; 81}; 82 83struct intxinfo { 84 int ii_count; |
85 int ii_pirq_pin; |
|
84 int ii_ioapic_irq; 85}; 86 87struct slotinfo { 88 struct intxinfo si_intpins[4]; 89 struct funcinfo si_funcs[MAXFUNCS]; 90}; 91 --- 16 unchanged lines hidden (view full) --- 108#define PCI_EMUL_IOLIMIT 0x10000 109 110#define PCI_EMUL_MEMLIMIT32 0xE0000000 /* 3.5GB */ 111 112#define PCI_EMUL_MEMBASE64 0xD000000000UL 113#define PCI_EMUL_MEMLIMIT64 0xFD00000000UL 114 115static struct pci_devemu *pci_emul_finddev(char *name); | 86 int ii_ioapic_irq; 87}; 88 89struct slotinfo { 90 struct intxinfo si_intpins[4]; 91 struct funcinfo si_funcs[MAXFUNCS]; 92}; 93 --- 16 unchanged lines hidden (view full) --- 110#define PCI_EMUL_IOLIMIT 0x10000 111 112#define PCI_EMUL_MEMLIMIT32 0xE0000000 /* 3.5GB */ 113 114#define PCI_EMUL_MEMBASE64 0xD000000000UL 115#define PCI_EMUL_MEMLIMIT64 0xFD00000000UL 116 117static struct pci_devemu *pci_emul_finddev(char *name); |
118static void pci_lintr_route(struct pci_devinst *pi); |
|
116static void pci_lintr_update(struct pci_devinst *pi); 117 118static struct mem_range pci_mem_hole; 119 120/* 121 * I/O access 122 */ 123 --- 585 unchanged lines hidden (view full) --- 709 710 pdi->pi_vmctx = ctx; 711 pdi->pi_bus = bus; 712 pdi->pi_slot = slot; 713 pdi->pi_func = func; 714 pthread_mutex_init(&pdi->pi_lintr.lock, NULL); 715 pdi->pi_lintr.pin = 0; 716 pdi->pi_lintr.state = IDLE; | 119static void pci_lintr_update(struct pci_devinst *pi); 120 121static struct mem_range pci_mem_hole; 122 123/* 124 * I/O access 125 */ 126 --- 585 unchanged lines hidden (view full) --- 712 713 pdi->pi_vmctx = ctx; 714 pdi->pi_bus = bus; 715 pdi->pi_slot = slot; 716 pdi->pi_func = func; 717 pthread_mutex_init(&pdi->pi_lintr.lock, NULL); 718 pdi->pi_lintr.pin = 0; 719 pdi->pi_lintr.state = IDLE; |
720 pdi->pi_lintr.pirq_pin = 0; |
|
717 pdi->pi_lintr.ioapic_irq = 0; 718 pdi->pi_d = pde; 719 snprintf(pdi->pi_name, PI_NAMESZ, "%s-pci-%d", pde->pe_emu, slot); 720 721 /* Disable legacy interrupts */ 722 pci_set_cfgdata8(pdi, PCIR_INTLINE, 255); 723 pci_set_cfgdata8(pdi, PCIR_INTPIN, 0); 724 --- 354 unchanged lines hidden (view full) --- 1079 1080 pci_emul_membase64 += BUSMEM_ROUNDUP; 1081 pci_emul_membase64 = roundup2(pci_emul_membase64, 1082 BUSMEM_ROUNDUP); 1083 bi->memlimit64 = pci_emul_membase64; 1084 } 1085 1086 /* | 721 pdi->pi_lintr.ioapic_irq = 0; 722 pdi->pi_d = pde; 723 snprintf(pdi->pi_name, PI_NAMESZ, "%s-pci-%d", pde->pe_emu, slot); 724 725 /* Disable legacy interrupts */ 726 pci_set_cfgdata8(pdi, PCIR_INTLINE, 255); 727 pci_set_cfgdata8(pdi, PCIR_INTPIN, 0); 728 --- 354 unchanged lines hidden (view full) --- 1083 1084 pci_emul_membase64 += BUSMEM_ROUNDUP; 1085 pci_emul_membase64 = roundup2(pci_emul_membase64, 1086 BUSMEM_ROUNDUP); 1087 bi->memlimit64 = pci_emul_membase64; 1088 } 1089 1090 /* |
1091 * PCI backends are initialized before routing INTx interrupts 1092 * so that LPC devices are able to reserve ISA IRQs before 1093 * routing PIRQ pins. 1094 */ 1095 for (bus = 0; bus < MAXBUSES; bus++) { 1096 if ((bi = pci_businfo[bus]) == NULL) 1097 continue; 1098 1099 for (slot = 0; slot < MAXSLOTS; slot++) { 1100 si = &bi->slotinfo[slot]; 1101 for (func = 0; func < MAXFUNCS; func++) { 1102 fi = &si->si_funcs[func]; 1103 if (fi->fi_devi == NULL) 1104 continue; 1105 pci_lintr_route(fi->fi_devi); 1106 } 1107 } 1108 } 1109 lpc_pirq_routed(); 1110 1111 /* |
|
1087 * The guest physical memory map looks like the following: 1088 * [0, lowmem) guest system memory 1089 * [lowmem, lowmem_limit) memory hole (may be absent) 1090 * [lowmem_limit, 4GB) PCI hole (32-bit BAR allocation) 1091 * [4GB, 4GB + highmem) 1092 * 1093 * Accesses to memory addresses that are not allocated to system 1094 * memory or PCI devices return 0xff's. --- 10 unchanged lines hidden (view full) --- 1105 1106 error = register_mem_fallback(&pci_mem_hole); 1107 assert(error == 0); 1108 1109 return (0); 1110} 1111 1112static void | 1112 * The guest physical memory map looks like the following: 1113 * [0, lowmem) guest system memory 1114 * [lowmem, lowmem_limit) memory hole (may be absent) 1115 * [lowmem_limit, 4GB) PCI hole (32-bit BAR allocation) 1116 * [4GB, 4GB + highmem) 1117 * 1118 * Accesses to memory addresses that are not allocated to system 1119 * memory or PCI devices return 0xff's. --- 10 unchanged lines hidden (view full) --- 1130 1131 error = register_mem_fallback(&pci_mem_hole); 1132 assert(error == 0); 1133 1134 return (0); 1135} 1136 1137static void |
1113pci_prt_entry(int bus, int slot, int pin, int ioapic_irq, void *arg) | 1138pci_apic_prt_entry(int bus, int slot, int pin, int pirq_pin, int ioapic_irq, 1139 void *arg) |
1114{ | 1140{ |
1115 int *count; | |
1116 | 1141 |
1117 count = arg; 1118 dsdt_line(" Package (0x04)"); | 1142 dsdt_line(" Package ()"); |
1119 dsdt_line(" {"); 1120 dsdt_line(" 0x%X,", slot << 16 | 0xffff); 1121 dsdt_line(" 0x%02X,", pin - 1); 1122 dsdt_line(" Zero,"); 1123 dsdt_line(" 0x%X", ioapic_irq); | 1143 dsdt_line(" {"); 1144 dsdt_line(" 0x%X,", slot << 16 | 0xffff); 1145 dsdt_line(" 0x%02X,", pin - 1); 1146 dsdt_line(" Zero,"); 1147 dsdt_line(" 0x%X", ioapic_irq); |
1124 dsdt_line(" }%s", *count == 1 ? "" : ","); 1125 (*count)--; | 1148 dsdt_line(" },"); |
1126} 1127 | 1149} 1150 |
1151static void 1152pci_pirq_prt_entry(int bus, int slot, int pin, int pirq_pin, int ioapic_irq, 1153 void *arg) 1154{ 1155 char *name; 1156 1157 name = lpc_pirq_name(pirq_pin); 1158 if (name == NULL) 1159 return; 1160 dsdt_line(" Package ()"); 1161 dsdt_line(" {"); 1162 dsdt_line(" 0x%X,", slot << 16 | 0xffff); 1163 dsdt_line(" 0x%02X,", pin - 1); 1164 dsdt_line(" %s,", name); 1165 dsdt_line(" 0x00"); 1166 dsdt_line(" },"); 1167 free(name); 1168} 1169 |
|
1128/* 1129 * A bhyve virtual machine has a flat PCI hierarchy with a root port 1130 * corresponding to each PCI bus. 1131 */ 1132static void 1133pci_bus_write_dsdt(int bus) 1134{ 1135 struct businfo *bi; 1136 struct slotinfo *si; 1137 struct pci_devinst *pi; | 1170/* 1171 * A bhyve virtual machine has a flat PCI hierarchy with a root port 1172 * corresponding to each PCI bus. 1173 */ 1174static void 1175pci_bus_write_dsdt(int bus) 1176{ 1177 struct businfo *bi; 1178 struct slotinfo *si; 1179 struct pci_devinst *pi; |
1138 int count, slot, func; | 1180 int count, func, slot; |
1139 1140 /* 1141 * If there are no devices on this 'bus' then just return. 1142 */ 1143 if ((bi = pci_businfo[bus]) == NULL) { 1144 /* 1145 * Bus 0 is special because it decodes the I/O ports used 1146 * for PCI config space access even if there are no devices 1147 * on it. 1148 */ 1149 if (bus != 0) 1150 return; 1151 } 1152 | 1181 1182 /* 1183 * If there are no devices on this 'bus' then just return. 1184 */ 1185 if ((bi = pci_businfo[bus]) == NULL) { 1186 /* 1187 * Bus 0 is special because it decodes the I/O ports used 1188 * for PCI config space access even if there are no devices 1189 * on it. 1190 */ 1191 if (bus != 0) 1192 return; 1193 } 1194 |
1153 dsdt_indent(1); 1154 dsdt_line("Scope (_SB)"); 1155 dsdt_line("{"); | |
1156 dsdt_line(" Device (PC%02X)", bus); 1157 dsdt_line(" {"); 1158 dsdt_line(" Name (_HID, EisaId (\"PNP0A03\"))"); 1159 dsdt_line(" Name (_ADR, Zero)"); 1160 1161 dsdt_line(" Method (_BBN, 0, NotSerialized)"); 1162 dsdt_line(" {"); 1163 dsdt_line(" Return (0x%08X)", bus); --- 76 unchanged lines hidden (view full) --- 1240 dsdt_line(" 0x%016lX, // Length\n", 1241 bi->memlimit64 - bi->membase64); 1242 dsdt_line(" ,, , AddressRangeMemory, TypeStatic)"); 1243 dsdt_line(" })"); 1244 1245 count = pci_count_lintr(bus); 1246 if (count != 0) { 1247 dsdt_indent(2); | 1195 dsdt_line(" Device (PC%02X)", bus); 1196 dsdt_line(" {"); 1197 dsdt_line(" Name (_HID, EisaId (\"PNP0A03\"))"); 1198 dsdt_line(" Name (_ADR, Zero)"); 1199 1200 dsdt_line(" Method (_BBN, 0, NotSerialized)"); 1201 dsdt_line(" {"); 1202 dsdt_line(" Return (0x%08X)", bus); --- 76 unchanged lines hidden (view full) --- 1279 dsdt_line(" 0x%016lX, // Length\n", 1280 bi->memlimit64 - bi->membase64); 1281 dsdt_line(" ,, , AddressRangeMemory, TypeStatic)"); 1282 dsdt_line(" })"); 1283 1284 count = pci_count_lintr(bus); 1285 if (count != 0) { 1286 dsdt_indent(2); |
1248 dsdt_line("Name (_PRT, Package (0x%02X)", count); | 1287 dsdt_line("Name (PPRT, Package ()"); |
1249 dsdt_line("{"); | 1288 dsdt_line("{"); |
1250 pci_walk_lintr(bus, pci_prt_entry, &count); 1251 dsdt_line("})"); | 1289 pci_walk_lintr(bus, pci_pirq_prt_entry, NULL); 1290 dsdt_line("})"); 1291 dsdt_line("Name (APRT, Package ()"); 1292 dsdt_line("{"); 1293 pci_walk_lintr(bus, pci_apic_prt_entry, NULL); 1294 dsdt_line("})"); 1295 dsdt_line("Method (_PRT, 0, NotSerialized)"); 1296 dsdt_line("{"); 1297 dsdt_line(" If (PICM)"); 1298 dsdt_line(" {"); 1299 dsdt_line(" Return (APRT)"); 1300 dsdt_line(" }"); 1301 dsdt_line(" Else"); 1302 dsdt_line(" {"); 1303 dsdt_line(" Return (PPRT)"); 1304 dsdt_line(" }"); 1305 dsdt_line("}"); |
1252 dsdt_unindent(2); 1253 } 1254 1255 dsdt_indent(2); 1256 for (slot = 0; slot < MAXSLOTS; slot++) { 1257 si = &bi->slotinfo[slot]; 1258 for (func = 0; func < MAXFUNCS; func++) { 1259 pi = si->si_funcs[func].fi_devi; 1260 if (pi != NULL && pi->pi_d->pe_write_dsdt != NULL) 1261 pi->pi_d->pe_write_dsdt(pi); 1262 } 1263 } 1264 dsdt_unindent(2); 1265done: 1266 dsdt_line(" }"); | 1306 dsdt_unindent(2); 1307 } 1308 1309 dsdt_indent(2); 1310 for (slot = 0; slot < MAXSLOTS; slot++) { 1311 si = &bi->slotinfo[slot]; 1312 for (func = 0; func < MAXFUNCS; func++) { 1313 pi = si->si_funcs[func].fi_devi; 1314 if (pi != NULL && pi->pi_d->pe_write_dsdt != NULL) 1315 pi->pi_d->pe_write_dsdt(pi); 1316 } 1317 } 1318 dsdt_unindent(2); 1319done: 1320 dsdt_line(" }"); |
1267 dsdt_line("}"); 1268 dsdt_unindent(1); | |
1269} 1270 1271void 1272pci_write_dsdt(void) 1273{ 1274 int bus; 1275 | 1321} 1322 1323void 1324pci_write_dsdt(void) 1325{ 1326 int bus; 1327 |
1328 dsdt_indent(1); 1329 dsdt_line("Name (PICM, 0x00)"); 1330 dsdt_line("Method (_PIC, 1, NotSerialized)"); 1331 dsdt_line("{"); 1332 dsdt_line(" Store (Arg0, PICM)"); 1333 dsdt_line("}"); 1334 dsdt_line(""); 1335 dsdt_line("Scope (_SB)"); 1336 dsdt_line("{"); |
|
1276 for (bus = 0; bus < MAXBUSES; bus++) 1277 pci_bus_write_dsdt(bus); | 1337 for (bus = 0; bus < MAXBUSES; bus++) 1338 pci_bus_write_dsdt(bus); |
1339 dsdt_line("}"); 1340 dsdt_unindent(1); |
|
1278} 1279 1280int 1281pci_bus_configured(int bus) 1282{ 1283 assert(bus >= 0 && bus < MAXBUSES); 1284 return (pci_businfo[bus] != NULL); 1285} --- 56 unchanged lines hidden (view full) --- 1342{ 1343 uint16_t cmd; 1344 1345 cmd = pci_get_cfgdata16(pi, PCIR_COMMAND); 1346 return (!(pi->pi_msi.enabled || pi->pi_msix.enabled || 1347 (cmd & PCIM_CMD_INTxDIS))); 1348} 1349 | 1341} 1342 1343int 1344pci_bus_configured(int bus) 1345{ 1346 assert(bus >= 0 && bus < MAXBUSES); 1347 return (pci_businfo[bus] != NULL); 1348} --- 56 unchanged lines hidden (view full) --- 1405{ 1406 uint16_t cmd; 1407 1408 cmd = pci_get_cfgdata16(pi, PCIR_COMMAND); 1409 return (!(pi->pi_msi.enabled || pi->pi_msix.enabled || 1410 (cmd & PCIM_CMD_INTxDIS))); 1411} 1412 |
1350int | 1413void |
1351pci_lintr_request(struct pci_devinst *pi) 1352{ 1353 struct businfo *bi; 1354 struct slotinfo *si; | 1414pci_lintr_request(struct pci_devinst *pi) 1415{ 1416 struct businfo *bi; 1417 struct slotinfo *si; |
1355 int bestpin, bestcount, irq, pin; | 1418 int bestpin, bestcount, pin; |
1356 1357 bi = pci_businfo[pi->pi_bus]; 1358 assert(bi != NULL); 1359 1360 /* | 1419 1420 bi = pci_businfo[pi->pi_bus]; 1421 assert(bi != NULL); 1422 1423 /* |
1361 * First, allocate a pin from our slot. | 1424 * Just allocate a pin from our slot. The pin will be 1425 * assigned IRQs later when interrupts are routed. |
1362 */ 1363 si = &bi->slotinfo[pi->pi_slot]; 1364 bestpin = 0; 1365 bestcount = si->si_intpins[0].ii_count; 1366 for (pin = 1; pin < 4; pin++) { 1367 if (si->si_intpins[pin].ii_count < bestcount) { 1368 bestpin = pin; 1369 bestcount = si->si_intpins[pin].ii_count; 1370 } 1371 } 1372 | 1426 */ 1427 si = &bi->slotinfo[pi->pi_slot]; 1428 bestpin = 0; 1429 bestcount = si->si_intpins[0].ii_count; 1430 for (pin = 1; pin < 4; pin++) { 1431 if (si->si_intpins[pin].ii_count < bestcount) { 1432 bestpin = pin; 1433 bestcount = si->si_intpins[pin].ii_count; 1434 } 1435 } 1436 |
1373 /* 1374 * Attempt to allocate an I/O APIC pin for this intpin. If 1375 * 8259A support is added we will need a separate field to 1376 * assign the intpin to an input pin on the PCI interrupt 1377 * router. 1378 */ 1379 if (si->si_intpins[bestpin].ii_count == 0) { 1380 irq = ioapic_pci_alloc_irq(); 1381 if (irq < 0) 1382 return (-1); 1383 si->si_intpins[bestpin].ii_ioapic_irq = irq; 1384 } else 1385 irq = si->si_intpins[bestpin].ii_ioapic_irq; | |
1386 si->si_intpins[bestpin].ii_count++; | 1437 si->si_intpins[bestpin].ii_count++; |
1387 | |
1388 pi->pi_lintr.pin = bestpin + 1; | 1438 pi->pi_lintr.pin = bestpin + 1; |
1389 pi->pi_lintr.ioapic_irq = irq; 1390 pci_set_cfgdata8(pi, PCIR_INTLINE, irq); | |
1391 pci_set_cfgdata8(pi, PCIR_INTPIN, bestpin + 1); | 1439 pci_set_cfgdata8(pi, PCIR_INTPIN, bestpin + 1); |
1392 return (0); | |
1393} 1394 | 1440} 1441 |
1442static void 1443pci_lintr_route(struct pci_devinst *pi) 1444{ 1445 struct businfo *bi; 1446 struct intxinfo *ii; 1447 1448 if (pi->pi_lintr.pin == 0) 1449 return; 1450 1451 bi = pci_businfo[pi->pi_bus]; 1452 assert(bi != NULL); 1453 ii = &bi->slotinfo[pi->pi_slot].si_intpins[pi->pi_lintr.pin - 1]; 1454 1455 /* 1456 * Attempt to allocate an I/O APIC pin for this intpin if one 1457 * is not yet assigned. 1458 */ 1459 if (ii->ii_ioapic_irq == 0) 1460 ii->ii_ioapic_irq = ioapic_pci_alloc_irq(); 1461 assert(ii->ii_ioapic_irq > 0); 1462 1463 /* 1464 * Attempt to allocate a PIRQ pin for this intpin if one is 1465 * not yet assigned. 1466 */ 1467 if (ii->ii_pirq_pin == 0) 1468 ii->ii_pirq_pin = pirq_alloc_pin(pi->pi_vmctx); 1469 assert(ii->ii_pirq_pin > 0); 1470 1471 pi->pi_lintr.ioapic_irq = ii->ii_ioapic_irq; 1472 pi->pi_lintr.pirq_pin = ii->ii_pirq_pin; 1473 pci_set_cfgdata8(pi, PCIR_INTLINE, pirq_irq(ii->ii_pirq_pin)); 1474} 1475 |
|
1395void 1396pci_lintr_assert(struct pci_devinst *pi) 1397{ 1398 1399 assert(pi->pi_lintr.pin > 0); 1400 1401 pthread_mutex_lock(&pi->pi_lintr.lock); 1402 if (pi->pi_lintr.state == IDLE) { 1403 if (pci_lintr_permitted(pi)) { 1404 pi->pi_lintr.state = ASSERTED; | 1476void 1477pci_lintr_assert(struct pci_devinst *pi) 1478{ 1479 1480 assert(pi->pi_lintr.pin > 0); 1481 1482 pthread_mutex_lock(&pi->pi_lintr.lock); 1483 if (pi->pi_lintr.state == IDLE) { 1484 if (pci_lintr_permitted(pi)) { 1485 pi->pi_lintr.state = ASSERTED; |
1405 vm_ioapic_assert_irq(pi->pi_vmctx, 1406 pi->pi_lintr.ioapic_irq); | 1486 pci_irq_assert(pi); |
1407 } else 1408 pi->pi_lintr.state = PENDING; 1409 } 1410 pthread_mutex_unlock(&pi->pi_lintr.lock); 1411} 1412 1413void 1414pci_lintr_deassert(struct pci_devinst *pi) 1415{ 1416 1417 assert(pi->pi_lintr.pin > 0); 1418 1419 pthread_mutex_lock(&pi->pi_lintr.lock); 1420 if (pi->pi_lintr.state == ASSERTED) { 1421 pi->pi_lintr.state = IDLE; | 1487 } else 1488 pi->pi_lintr.state = PENDING; 1489 } 1490 pthread_mutex_unlock(&pi->pi_lintr.lock); 1491} 1492 1493void 1494pci_lintr_deassert(struct pci_devinst *pi) 1495{ 1496 1497 assert(pi->pi_lintr.pin > 0); 1498 1499 pthread_mutex_lock(&pi->pi_lintr.lock); 1500 if (pi->pi_lintr.state == ASSERTED) { 1501 pi->pi_lintr.state = IDLE; |
1422 vm_ioapic_deassert_irq(pi->pi_vmctx, pi->pi_lintr.ioapic_irq); | 1502 pci_irq_deassert(pi); |
1423 } else if (pi->pi_lintr.state == PENDING) 1424 pi->pi_lintr.state = IDLE; 1425 pthread_mutex_unlock(&pi->pi_lintr.lock); 1426} 1427 1428static void 1429pci_lintr_update(struct pci_devinst *pi) 1430{ 1431 1432 pthread_mutex_lock(&pi->pi_lintr.lock); 1433 if (pi->pi_lintr.state == ASSERTED && !pci_lintr_permitted(pi)) { | 1503 } else if (pi->pi_lintr.state == PENDING) 1504 pi->pi_lintr.state = IDLE; 1505 pthread_mutex_unlock(&pi->pi_lintr.lock); 1506} 1507 1508static void 1509pci_lintr_update(struct pci_devinst *pi) 1510{ 1511 1512 pthread_mutex_lock(&pi->pi_lintr.lock); 1513 if (pi->pi_lintr.state == ASSERTED && !pci_lintr_permitted(pi)) { |
1434 vm_ioapic_deassert_irq(pi->pi_vmctx, pi->pi_lintr.ioapic_irq); | 1514 pci_irq_deassert(pi); |
1435 pi->pi_lintr.state = PENDING; 1436 } else if (pi->pi_lintr.state == PENDING && pci_lintr_permitted(pi)) { 1437 pi->pi_lintr.state = ASSERTED; | 1515 pi->pi_lintr.state = PENDING; 1516 } else if (pi->pi_lintr.state == PENDING && pci_lintr_permitted(pi)) { 1517 pi->pi_lintr.state = ASSERTED; |
1438 vm_ioapic_assert_irq(pi->pi_vmctx, pi->pi_lintr.ioapic_irq); | 1518 pci_irq_assert(pi); |
1439 } 1440 pthread_mutex_unlock(&pi->pi_lintr.lock); 1441} 1442 1443int 1444pci_count_lintr(int bus) 1445{ 1446 int count, slot, pin; --- 23 unchanged lines hidden (view full) --- 1470 if ((bi = pci_businfo[bus]) == NULL) 1471 return; 1472 1473 for (slot = 0; slot < MAXSLOTS; slot++) { 1474 si = &bi->slotinfo[slot]; 1475 for (pin = 0; pin < 4; pin++) { 1476 ii = &si->si_intpins[pin]; 1477 if (ii->ii_count != 0) | 1519 } 1520 pthread_mutex_unlock(&pi->pi_lintr.lock); 1521} 1522 1523int 1524pci_count_lintr(int bus) 1525{ 1526 int count, slot, pin; --- 23 unchanged lines hidden (view full) --- 1550 if ((bi = pci_businfo[bus]) == NULL) 1551 return; 1552 1553 for (slot = 0; slot < MAXSLOTS; slot++) { 1554 si = &bi->slotinfo[slot]; 1555 for (pin = 0; pin < 4; pin++) { 1556 ii = &si->si_intpins[pin]; 1557 if (ii->ii_count != 0) |
1478 cb(bus, slot, pin + 1, ii->ii_ioapic_irq, arg); | 1558 cb(bus, slot, pin + 1, ii->ii_pirq_pin, 1559 ii->ii_ioapic_irq, arg); |
1479 } 1480 } 1481} 1482 1483/* 1484 * Return 1 if the emulated device in 'slot' is a multi-function device. 1485 * Return 0 otherwise. 1486 */ --- 280 unchanged lines hidden (view full) --- 1767 return (0); 1768} 1769 1770INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+0, IOPORT_F_INOUT, pci_emul_cfgdata); 1771INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+1, IOPORT_F_INOUT, pci_emul_cfgdata); 1772INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+2, IOPORT_F_INOUT, pci_emul_cfgdata); 1773INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+3, IOPORT_F_INOUT, pci_emul_cfgdata); 1774 | 1560 } 1561 } 1562} 1563 1564/* 1565 * Return 1 if the emulated device in 'slot' is a multi-function device. 1566 * Return 0 otherwise. 1567 */ --- 280 unchanged lines hidden (view full) --- 1848 return (0); 1849} 1850 1851INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+0, IOPORT_F_INOUT, pci_emul_cfgdata); 1852INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+1, IOPORT_F_INOUT, pci_emul_cfgdata); 1853INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+2, IOPORT_F_INOUT, pci_emul_cfgdata); 1854INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+3, IOPORT_F_INOUT, pci_emul_cfgdata); 1855 |
1775/* 1776 * I/O ports to configure PCI IRQ routing. We ignore all writes to it. 1777 */ 1778static int 1779pci_irq_port_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, 1780 uint32_t *eax, void *arg) 1781{ 1782 assert(in == 0); 1783 return (0); 1784} 1785INOUT_PORT(pci_irq, 0xC00, IOPORT_F_OUT, pci_irq_port_handler); 1786INOUT_PORT(pci_irq, 0xC01, IOPORT_F_OUT, pci_irq_port_handler); 1787SYSRES_IO(0xC00, 2); 1788 | |
1789#define PCI_EMUL_TEST 1790#ifdef PCI_EMUL_TEST 1791/* 1792 * Define a dummy test device 1793 */ 1794#define DIOSZ 8 1795#define DMEMSZ 4096 1796struct pci_emul_dsoftc { --- 161 unchanged lines hidden --- | 1856#define PCI_EMUL_TEST 1857#ifdef PCI_EMUL_TEST 1858/* 1859 * Define a dummy test device 1860 */ 1861#define DIOSZ 8 1862#define DMEMSZ 4096 1863struct pci_emul_dsoftc { --- 161 unchanged lines hidden --- |