Page MenuHomeFreeBSD

D39284.id119503.diff
No OneTemporary

D39284.id119503.diff

diff --git a/usr.sbin/bhyve/pci_emul.h b/usr.sbin/bhyve/pci_emul.h
--- a/usr.sbin/bhyve/pci_emul.h
+++ b/usr.sbin/bhyve/pci_emul.h
@@ -234,6 +234,8 @@
enum pcibar_type type, uint64_t size);
int pci_emul_alloc_rom(struct pci_devinst *const pdi, const uint64_t size,
void **const addr);
+int pci_emul_add_boot_device(struct pci_devinst *const pi,
+ const int bootindex);
int pci_emul_add_msicap(struct pci_devinst *pi, int msgnum);
int pci_emul_add_pciecap(struct pci_devinst *pi, int pcie_device_type);
void pci_emul_capwrite(struct pci_devinst *pi, int offset, int bytes,
diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c
--- a/usr.sbin/bhyve/pci_emul.c
+++ b/usr.sbin/bhyve/pci_emul.c
@@ -62,6 +62,7 @@
#include "pci_irq.h"
#include "pci_lpc.h"
#include "pci_passthru.h"
+#include "qemu_fwcfg.h"
#define CONF1_ADDR_PORT 0x0cf8
#define CONF1_DATA_PORT 0x0cfc
@@ -121,6 +122,14 @@
static TAILQ_HEAD(pci_bar_list, pci_bar_allocation) pci_bars =
TAILQ_HEAD_INITIALIZER(pci_bars);
+struct boot_device {
+ TAILQ_ENTRY(boot_device) boot_device_chain;
+ struct pci_devinst *pdi;
+ int bootindex;
+};
+static TAILQ_HEAD(boot_list, boot_device) boot_devices = TAILQ_HEAD_INITIALIZER(
+ boot_devices);
+
#define PCI_EMUL_IOBASE 0x2000
#define PCI_EMUL_IOLIMIT 0x10000
@@ -955,6 +964,43 @@
return (0);
}
+int
+pci_emul_add_boot_device(struct pci_devinst *pi, int bootindex)
+{
+ /* don't permit a negative bootindex */
+ if (bootindex < 0) {
+ errx(4, "Invalid bootindex %d for %s", bootindex, pi->pi_name);
+ }
+ /* alloc new boot device */
+ struct boot_device *new_device = calloc(1, sizeof(struct boot_device));
+ if (new_device == NULL) {
+ return (-ENOMEM);
+ }
+ new_device->pdi = pi;
+ new_device->bootindex = bootindex;
+
+ /* search for boot device with higher boot index */
+ struct boot_device *device;
+ TAILQ_FOREACH(device, &boot_devices, boot_device_chain) {
+ if (device->bootindex == bootindex) {
+ errx(4,
+ "Could not set bootindex %d for %s. Bootindex already occupied by %s\n",
+ bootindex, pi->pi_name, device->pdi->pi_name);
+ } else if (device->bootindex > bootindex) {
+ break;
+ }
+ }
+
+ /* add boot device to queue */
+ if (device == NULL) {
+ TAILQ_INSERT_TAIL(&boot_devices, new_device, boot_device_chain);
+ } else {
+ TAILQ_INSERT_BEFORE(device, new_device, boot_device_chain);
+ }
+
+ return (0);
+}
+
#define CAP_START_OFFSET 0x40
static int
pci_emul_add_capability(struct pci_devinst *pi, u_char *capdata, int caplen)
@@ -1361,6 +1407,40 @@
return (PCI_EMUL_ECFG_BASE);
}
+static int
+init_bootorder()
+{
+ if (TAILQ_EMPTY(&boot_devices)) {
+ return (0);
+ }
+
+ struct boot_device *device;
+ uint8_t *bootorder = NULL;
+ uint64_t bootorder_len = 0;
+ TAILQ_FOREACH(device, &boot_devices, boot_device_chain) {
+ /* get bootpath string */
+ uint8_t bootpath[NAME_MAX];
+ snprintf(bootpath, NAME_MAX, "/pci@i0cf8/pci@%d,%d\n",
+ device->pdi->pi_slot, device->pdi->pi_func);
+
+ /* realloc bootorder string */
+ const uint64_t bootpath_len = strlen(bootpath);
+ bootorder = realloc(bootorder, bootorder_len + bootpath_len);
+ if (bootorder == NULL) {
+ return (-ENOMEM);
+ }
+
+ /* copy new entry to bootorder */
+ memcpy(&bootorder[bootorder_len], bootpath, bootpath_len);
+ bootorder_len += bootpath_len;
+ }
+ /* bootorder should be '\0' terminated */
+ bootorder[bootorder_len - 1] = '\0';
+
+ return qemu_fwcfg_add_file("bootorder", bootorder_len,
+ (void *)bootorder);
+}
+
#define BUSIO_ROUNDUP 32
#define BUSMEM32_ROUNDUP (1024 * 1024)
#define BUSMEM64_ROUNDUP (512 * 1024 * 1024)
@@ -1390,6 +1470,8 @@
pci_emul_membase64 = roundup2(pci_emul_membase64, PCI_EMUL_MEMSIZE64);
pci_emul_memlim64 = pci_emul_membase64 + PCI_EMUL_MEMSIZE64;
+ TAILQ_INIT(&boot_devices);
+
for (bus = 0; bus < MAXBUSES; bus++) {
snprintf(node_name, sizeof(node_name), "pci.%d", bus);
nvl = find_config_node(node_name);
@@ -1497,6 +1579,14 @@
}
lpc_pirq_routed();
+ /*
+ * Set up boot order
+ */
+ if ((error = init_bootorder()) != 0) {
+ warnx("%s: Unable to init bootorder\n", __func__);
+ return (-1);
+ }
+
/*
* The guest physical memory map looks like the following:
* [0, lowmem) guest system memory

File Metadata

Mime Type
text/plain
Expires
Wed, Aug 26, 9:17 AM (4 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37260188
Default Alt Text
D39284.id119503.diff (4 KB)

Event Timeline