Deleted Added
full compact
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 ---