diff options
author | Corvin Köhne <corvink@FreeBSD.org> | 2021-08-11 07:59:16 +0000 |
---|---|---|
committer | Corvin Köhne <corvink@FreeBSD.org> | 2023-02-14 07:28:43 +0000 |
commit | 151d8131a817e7a6a629e9bb7fde4d7a158e5211 (patch) | |
tree | 9957bec4a6a0536fde01f5c6b844f633cfba67e5 | |
parent | 9b99de77f16029dd55326e0210072b14ec1ad960 (diff) | |
download | src-151d8131a817e7a6a629e9bb7fde4d7a158e5211.tar.gz src-151d8131a817e7a6a629e9bb7fde4d7a158e5211.zip |
bhyve: add emulation for the qemu fwcfg selector port
The selector port is used to select the desired fwcfg item.
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D38332
-rw-r--r-- | usr.sbin/bhyve/qemu_fwcfg.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/usr.sbin/bhyve/qemu_fwcfg.c b/usr.sbin/bhyve/qemu_fwcfg.c index 5d3070abf285..dec3fa83c493 100644 --- a/usr.sbin/bhyve/qemu_fwcfg.c +++ b/usr.sbin/bhyve/qemu_fwcfg.c @@ -29,8 +29,33 @@ #define QEMU_FWCFG_DATA_PORT_FLAGS \ IOPORT_F_INOUT /* QEMU v2.4+ ignores writes */ +#define QEMU_FWCFG_ARCHITECTURE_MASK 0x0001 +#define QEMU_FWCFG_INDEX_MASK 0x3FFF + +#define QEMU_FWCFG_SELECT_READ 0 +#define QEMU_FWCFG_SELECT_WRITE 1 + +#define QEMU_FWCFG_ARCHITECTURE_GENERIC 0 +#define QEMU_FWCFG_ARCHITECTURE_SPECIFIC 1 + +#pragma pack(1) + +union qemu_fwcfg_selector { + struct { + uint16_t index : 14; + uint16_t writeable : 1; + uint16_t architecture : 1; + }; + uint16_t bits; +}; + +#pragma pack() + struct qemu_fwcfg_softc { struct acpi_device *acpi_dev; + + uint32_t data_offset; + union qemu_fwcfg_selector selector; }; static struct qemu_fwcfg_softc fwcfg_sc; @@ -40,6 +65,20 @@ qemu_fwcfg_selector_port_handler(struct vmctx *const ctx __unused, const int in, const int port __unused, const int bytes, uint32_t *const eax, void *const arg __unused) { + if (bytes != sizeof(uint16_t)) { + warnx("%s: invalid size (%d) of IO port access", __func__, + bytes); + return (-1); + } + + if (in) { + *eax = htole16(fwcfg_sc.selector.bits); + return (0); + } + + fwcfg_sc.data_offset = 0; + fwcfg_sc.selector.bits = le16toh(*eax); + return (0); } |