aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lguest
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2015-02-10 23:45:11 -0500
committerRusty Russell <rusty@rustcorp.com.au>2015-02-11 01:17:36 -0500
commitd7fbf6e95e2c5e7ef97c463a97499d7a2341fb09 (patch)
treeeb883c2c3178fa297cfa473b9dd572e88dd0534a /tools/lguest
parent6a54f9ab0d65a2095de50160b8ca7ce6469aaac0 (diff)
lguest: add PCI config space emulation to example launcher.
This handles ioport 0xCF8 and 0xCFC accesses, which are used to read/write PCI device config space. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'tools/lguest')
-rw-r--r--tools/lguest/lguest.c216
1 files changed, 211 insertions, 5 deletions
diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c
index e52a3571076a..0f29657fc065 100644
--- a/tools/lguest/lguest.c
+++ b/tools/lguest/lguest.c
@@ -42,6 +42,7 @@
42#include <pwd.h> 42#include <pwd.h>
43#include <grp.h> 43#include <grp.h>
44#include <sys/user.h> 44#include <sys/user.h>
45#include <linux/pci_regs.h>
45 46
46#ifndef VIRTIO_F_ANY_LAYOUT 47#ifndef VIRTIO_F_ANY_LAYOUT
47#define VIRTIO_F_ANY_LAYOUT 27 48#define VIRTIO_F_ANY_LAYOUT 27
@@ -125,6 +126,21 @@ struct device_list {
125/* The list of Guest devices, based on command line arguments. */ 126/* The list of Guest devices, based on command line arguments. */
126static struct device_list devices; 127static struct device_list devices;
127 128
129/* This is the layout (little-endian) of the PCI config space. */
130struct pci_config {
131 u16 vendor_id, device_id;
132 u16 command, status;
133 u8 revid, prog_if, subclass, class;
134 u8 cacheline_size, lat_timer, header_type, bist;
135 u32 bar[6];
136 u32 cardbus_cis_ptr;
137 u16 subsystem_vendor_id, subsystem_device_id;
138 u32 expansion_rom_addr;
139 u8 capabilities, reserved1[3];
140 u32 reserved2;
141 u8 irq_line, irq_pin, min_grant, max_latency;
142};
143
128/* The device structure describes a single device. */ 144/* The device structure describes a single device. */
129struct device { 145struct device {
130 /* The linked-list pointer. */ 146 /* The linked-list pointer. */
@@ -146,6 +162,15 @@ struct device {
146 /* Is it operational */ 162 /* Is it operational */
147 bool running; 163 bool running;
148 164
165 /* PCI configuration */
166 union {
167 struct pci_config config;
168 u32 config_words[sizeof(struct pci_config) / sizeof(u32)];
169 };
170
171 /* Device-specific config hangs off the end of this. */
172 struct virtio_pci_mmio *mmio;
173
149 /* PCI MMIO resources (all in BAR0) */ 174 /* PCI MMIO resources (all in BAR0) */
150 size_t mmio_size; 175 size_t mmio_size;
151 u32 mmio_addr; 176 u32 mmio_addr;
@@ -1173,6 +1198,169 @@ static void handle_output(unsigned long addr)
1173 strnlen(from_guest_phys(addr), guest_limit - addr)); 1198 strnlen(from_guest_phys(addr), guest_limit - addr));
1174} 1199}
1175 1200
1201/*L:217
1202 * We do PCI. This is mainly done to let us test the kernel virtio PCI
1203 * code.
1204 */
1205
1206/* The IO ports used to read the PCI config space. */
1207#define PCI_CONFIG_ADDR 0xCF8
1208#define PCI_CONFIG_DATA 0xCFC
1209
1210/*
1211 * Not really portable, but does help readability: this is what the Guest
1212 * writes to the PCI_CONFIG_ADDR IO port.
1213 */
1214union pci_config_addr {
1215 struct {
1216 unsigned mbz: 2;
1217 unsigned offset: 6;
1218 unsigned funcnum: 3;
1219 unsigned devnum: 5;
1220 unsigned busnum: 8;
1221 unsigned reserved: 7;
1222 unsigned enabled : 1;
1223 } bits;
1224 u32 val;
1225};
1226
1227/*
1228 * We cache what they wrote to the address port, so we know what they're
1229 * talking about when they access the data port.
1230 */
1231static union pci_config_addr pci_config_addr;
1232
1233static struct device *find_pci_device(unsigned int index)
1234{
1235 return devices.pci[index];
1236}
1237
1238/* PCI can do 1, 2 and 4 byte reads; we handle that here. */
1239static void ioread(u16 off, u32 v, u32 mask, u32 *val)
1240{
1241 assert(off < 4);
1242 assert(mask == 0xFF || mask == 0xFFFF || mask == 0xFFFFFFFF);
1243 *val = (v >> (off * 8)) & mask;
1244}
1245
1246/* PCI can do 1, 2 and 4 byte writes; we handle that here. */
1247static void iowrite(u16 off, u32 v, u32 mask, u32 *dst)
1248{
1249 assert(off < 4);
1250 assert(mask == 0xFF || mask == 0xFFFF || mask == 0xFFFFFFFF);
1251 *dst &= ~(mask << (off * 8));
1252 *dst |= (v & mask) << (off * 8);
1253}
1254
1255/*
1256 * Where PCI_CONFIG_DATA accesses depends on the previous write to
1257 * PCI_CONFIG_ADDR.
1258 */
1259static struct device *dev_and_reg(u32 *reg)
1260{
1261 if (!pci_config_addr.bits.enabled)
1262 return NULL;
1263
1264 if (pci_config_addr.bits.funcnum != 0)
1265 return NULL;
1266
1267 if (pci_config_addr.bits.busnum != 0)
1268 return NULL;
1269
1270 if (pci_config_addr.bits.offset * 4 >= sizeof(struct pci_config))
1271 return NULL;
1272
1273 *reg = pci_config_addr.bits.offset;
1274 return find_pci_device(pci_config_addr.bits.devnum);
1275}
1276
1277/* Is this accessing the PCI config address port?. */
1278static bool is_pci_addr_port(u16 port)
1279{
1280 return port >= PCI_CONFIG_ADDR && port < PCI_CONFIG_ADDR + 4;
1281}
1282
1283static bool pci_addr_iowrite(u16 port, u32 mask, u32 val)
1284{
1285 iowrite(port - PCI_CONFIG_ADDR, val, mask,
1286 &pci_config_addr.val);
1287 verbose("PCI%s: %#x/%x: bus %u dev %u func %u reg %u\n",
1288 pci_config_addr.bits.enabled ? "" : " DISABLED",
1289 val, mask,
1290 pci_config_addr.bits.busnum,
1291 pci_config_addr.bits.devnum,
1292 pci_config_addr.bits.funcnum,
1293 pci_config_addr.bits.offset);
1294 return true;
1295}
1296
1297static void pci_addr_ioread(u16 port, u32 mask, u32 *val)
1298{
1299 ioread(port - PCI_CONFIG_ADDR, pci_config_addr.val, mask, val);
1300}
1301
1302/* Is this accessing the PCI config data port?. */
1303static bool is_pci_data_port(u16 port)
1304{
1305 return port >= PCI_CONFIG_DATA && port < PCI_CONFIG_DATA + 4;
1306}
1307
1308static bool pci_data_iowrite(u16 port, u32 mask, u32 val)
1309{
1310 u32 reg, portoff;
1311 struct device *d = dev_and_reg(&reg);
1312
1313 /* Complain if they don't belong to a device. */
1314 if (!d)
1315 return false;
1316
1317 /* They can do 1 byte writes, etc. */
1318 portoff = port - PCI_CONFIG_DATA;
1319
1320 /*
1321 * PCI uses a weird way to determine the BAR size: the OS
1322 * writes all 1's, and sees which ones stick.
1323 */
1324 if (&d->config_words[reg] == &d->config.bar[0]) {
1325 int i;
1326
1327 iowrite(portoff, val, mask, &d->config.bar[0]);
1328 for (i = 0; (1 << i) < d->mmio_size; i++)
1329 d->config.bar[0] &= ~(1 << i);
1330 return true;
1331 } else if ((&d->config_words[reg] > &d->config.bar[0]
1332 && &d->config_words[reg] <= &d->config.bar[6])
1333 || &d->config_words[reg] == &d->config.expansion_rom_addr) {
1334 /* Allow writing to any other BAR, or expansion ROM */
1335 iowrite(portoff, val, mask, &d->config_words[reg]);
1336 return true;
1337 /* We let them overide latency timer and cacheline size */
1338 } else if (&d->config_words[reg] == (void *)&d->config.cacheline_size) {
1339 /* Only let them change the first two fields. */
1340 if (mask == 0xFFFFFFFF)
1341 mask = 0xFFFF;
1342 iowrite(portoff, val, mask, &d->config_words[reg]);
1343 return true;
1344 } else if (&d->config_words[reg] == (void *)&d->config.command
1345 && mask == 0xFFFF) {
1346 /* Ignore command writes. */
1347 return true;
1348 }
1349
1350 /* Complain about other writes. */
1351 return false;
1352}
1353
1354static void pci_data_ioread(u16 port, u32 mask, u32 *val)
1355{
1356 u32 reg;
1357 struct device *d = dev_and_reg(&reg);
1358
1359 if (!d)
1360 return;
1361 ioread(port - PCI_CONFIG_DATA, d->config_words[reg], mask, val);
1362}
1363
1176/*L:216 1364/*L:216
1177 * This is where we emulate a handful of Guest instructions. It's ugly 1365 * This is where we emulate a handful of Guest instructions. It's ugly
1178 * and we used to do it in the kernel but it grew over time. 1366 * and we used to do it in the kernel but it grew over time.
@@ -1284,7 +1472,7 @@ static void emulate_insn(const u8 insn[])
1284 unsigned int insnlen = 0, in = 0, small_operand = 0, byte_access; 1472 unsigned int insnlen = 0, in = 0, small_operand = 0, byte_access;
1285 unsigned int eax, port, mask; 1473 unsigned int eax, port, mask;
1286 /* 1474 /*
1287 * We always return all-ones on IO port reads, which traditionally 1475 * Default is to return all-ones on IO port reads, which traditionally
1288 * means "there's nothing there". 1476 * means "there's nothing there".
1289 */ 1477 */
1290 u32 val = 0xFFFFFFFF; 1478 u32 val = 0xFFFFFFFF;
@@ -1359,10 +1547,6 @@ static void emulate_insn(const u8 insn[])
1359 else 1547 else
1360 mask = 0xFFFFFFFF; 1548 mask = 0xFFFFFFFF;
1361 1549
1362 /* This is the PS/2 keyboard status; 1 means ready for output */
1363 if (port == 0x64)
1364 val = 1;
1365
1366 /* 1550 /*
1367 * If it was an "IN" instruction, they expect the result to be read 1551 * If it was an "IN" instruction, they expect the result to be read
1368 * into %eax, so we change %eax. 1552 * into %eax, so we change %eax.
@@ -1370,12 +1554,30 @@ static void emulate_insn(const u8 insn[])
1370 eax = getreg(eax); 1554 eax = getreg(eax);
1371 1555
1372 if (in) { 1556 if (in) {
1557 /* This is the PS/2 keyboard status; 1 means ready for output */
1558 if (port == 0x64)
1559 val = 1;
1560 else if (is_pci_addr_port(port))
1561 pci_addr_ioread(port, mask, &val);
1562 else if (is_pci_data_port(port))
1563 pci_data_ioread(port, mask, &val);
1564
1373 /* Clear the bits we're about to read */ 1565 /* Clear the bits we're about to read */
1374 eax &= ~mask; 1566 eax &= ~mask;
1375 /* Copy bits in from val. */ 1567 /* Copy bits in from val. */
1376 eax |= val & mask; 1568 eax |= val & mask;
1377 /* Now update the register. */ 1569 /* Now update the register. */
1378 setreg(eax, eax); 1570 setreg(eax, eax);
1571 } else {
1572 if (is_pci_addr_port(port)) {
1573 if (!pci_addr_iowrite(port, mask, eax))
1574 goto bad_io;
1575 } else if (is_pci_data_port(port)) {
1576 if (!pci_data_iowrite(port, mask, eax))
1577 goto bad_io;
1578 }
1579 /* There are many other ports, eg. CMOS clock, serial
1580 * and parallel ports, so we ignore them all. */
1379 } 1581 }
1380 1582
1381 verbose("IO %s of %x to %u: %#08x\n", 1583 verbose("IO %s of %x to %u: %#08x\n",
@@ -1385,6 +1587,10 @@ skip_insn:
1385 setreg(eip, getreg(eip) + insnlen); 1587 setreg(eip, getreg(eip) + insnlen);
1386 return; 1588 return;
1387 1589
1590bad_io:
1591 warnx("Attempt to %s port %u (%#x mask)",
1592 in ? "read from" : "write to", port, mask);
1593
1388no_emulate: 1594no_emulate:
1389 /* Inject trap into Guest. */ 1595 /* Inject trap into Guest. */
1390 if (write(lguest_fd, args, sizeof(args)) < 0) 1596 if (write(lguest_fd, args, sizeof(args)) < 0)