-/* $OpenBSD: fw_cfg.c,v 1.6 2022/12/26 23:50:20 dv Exp $ */
+/* $OpenBSD: fw_cfg.c,v 1.7 2023/02/06 20:33:34 dv Exp $ */
/*
* Copyright (c) 2018 Claudio Jeker <claudio@openbsd.org>
*
#include <sys/uio.h>
#include <machine/biosvar.h> /* bios_memmap_t */
#include <machine/vmmvar.h>
+#include <dev/pv/virtioreg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "atomicio.h"
+#include "pci.h"
#include "vmd.h"
#include "vmm.h"
#include "fw_cfg.h"
void
fw_cfg_init(struct vmop_create_params *vmc)
{
- const char *bootorder = NULL;
unsigned int sd = 0;
size_t i, e820_len = 0;
+ char bootorder[64];
+ const char *bootfmt;
+ int bootidx = -1;
/* Define e820 memory ranges. */
memset(&e820, 0, sizeof(e820));
switch (vmc->vmc_bootdevice) {
case VMBOOTDEV_DISK:
- bootorder = "/pci@i0cf8/*@3\nHALT";
+ bootidx = pci_find_first_device(PCI_PRODUCT_VIRTIO_BLOCK);
+ bootfmt = "/pci@i0cf8/*@%d\nHALT";
break;
case VMBOOTDEV_CDROM:
- bootorder = "/pci@i0cf8/*@4/*@0/*@0,40000100\nHALT";
+ bootidx = pci_find_first_device(PCI_PRODUCT_VIRTIO_SCSI);
+ bootfmt = "/pci@i0cf8/*@%d/*@0/*@0,40000100\nHALT";
break;
case VMBOOTDEV_NET:
/* XXX not yet */
- bootorder = "HALT";
+ bootidx = pci_find_first_device(PCI_PRODUCT_VIRTIO_NETWORK);
+ bootfmt = "HALT";
break;
}
- if (bootorder)
+ if (bootidx > -1) {
+ snprintf(bootorder, sizeof(bootorder), bootfmt, bootidx);
+ log_debug("%s: bootorder: %s", __func__, bootorder);
fw_cfg_add_file("bootorder", bootorder, strlen(bootorder) + 1);
+ }
}
int
-/* $OpenBSD: pci.c,v 1.30 2023/01/28 14:40:53 dv Exp $ */
+/* $OpenBSD: pci.c,v 1.31 2023/02/06 20:33:34 dv Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
}
return (0);
}
+
+/*
+ * Find the first PCI device based on PCI Subsystem ID
+ * (e.g. PCI_PRODUCT_VIRTIO_BLOCK).
+ *
+ * Returns the PCI device id of the first matching device, if found.
+ * Otherwise, returns -1.
+ */
+int
+pci_find_first_device(uint16_t subsys_id)
+{
+ int i;
+
+ for (i = 0; i < pci.pci_dev_ct; i++)
+ if (pci.pci_devices[i].pd_subsys_id == subsys_id)
+ return (i);
+ return (-1);
+}
-/* $OpenBSD: pci.h,v 1.9 2021/06/16 16:55:02 dv Exp $ */
+/* $OpenBSD: pci.h,v 1.10 2023/02/06 20:33:34 dv Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
struct pci_dev pci_devices[PCI_CONFIG_MAX_DEV];
};
+int pci_find_first_device(uint16_t);
void pci_handle_address_reg(struct vm_run_params *);
void pci_handle_data_reg(struct vm_run_params *);
uint8_t pci_handle_io(struct vm_run_params *);
-/* $OpenBSD: vm.c,v 1.82 2023/01/28 14:40:53 dv Exp $ */
+/* $OpenBSD: vm.c,v 1.83 2023/02/06 20:33:34 dv Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
for (i = COM1_DATA; i <= COM1_SCR; i++)
ioports_map[i] = vcpu_exit_com;
- /* Init QEMU fw_cfg interface */
- fw_cfg_init(vmc);
- ioports_map[FW_CFG_IO_SELECT] = vcpu_exit_fw_cfg;
- ioports_map[FW_CFG_IO_DATA] = vcpu_exit_fw_cfg;
- ioports_map[FW_CFG_IO_DMA_ADDR_HIGH] = vcpu_exit_fw_cfg_dma;
- ioports_map[FW_CFG_IO_DMA_ADDR_LOW] = vcpu_exit_fw_cfg_dma;
-
/* Initialize PCI */
for (i = VM_PCI_IO_BAR_BASE; i <= VM_PCI_IO_BAR_END; i++)
ioports_map[i] = vcpu_exit_pci;
/* Initialize virtio devices */
virtio_init(current_vm, child_cdrom, child_disks, child_taps);
+
+ /*
+ * Init QEMU fw_cfg interface. Must be done last for pci hardware
+ * detection.
+ */
+ fw_cfg_init(vmc);
+ ioports_map[FW_CFG_IO_SELECT] = vcpu_exit_fw_cfg;
+ ioports_map[FW_CFG_IO_DATA] = vcpu_exit_fw_cfg;
+ ioports_map[FW_CFG_IO_DMA_ADDR_HIGH] = vcpu_exit_fw_cfg_dma;
+ ioports_map[FW_CFG_IO_DMA_ADDR_LOW] = vcpu_exit_fw_cfg_dma;
}
+
/*
* restore_emulated_hw
*