Page MenuHomeFreeBSD

D36984.id112907.diff
No OneTemporary

D36984.id112907.diff

diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile
--- a/usr.sbin/bhyve/Makefile
+++ b/usr.sbin/bhyve/Makefile
@@ -18,6 +18,7 @@
atkbdc.c \
acpi.c \
audio.c \
+ basl.c \
bhyvegc.c \
bhyverun.c \
block_if.c \
diff --git a/usr.sbin/bhyve/acpi.c b/usr.sbin/bhyve/acpi.c
--- a/usr.sbin/bhyve/acpi.c
+++ b/usr.sbin/bhyve/acpi.c
@@ -73,6 +73,7 @@
#include "bhyverun.h"
#include "acpi.h"
+#include "basl.h"
#include "pci_emul.h"
#include "vmgenc.h"
@@ -80,7 +81,6 @@
* Define the base address of the ACPI tables, the sizes of some tables,
* and the offsets to the individual tables,
*/
-#define BHYVE_ACPI_BASE 0xf2400
#define RSDT_OFFSET 0x040
#define XSDT_OFFSET 0x080
#define MADT_OFFSET 0x100
diff --git a/usr.sbin/bhyve/basl.h b/usr.sbin/bhyve/basl.h
new file mode 100644
--- /dev/null
+++ b/usr.sbin/bhyve/basl.h
@@ -0,0 +1,37 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2022 Beckhoff Automation GmbH & Co. KG
+ * Author: Corvin Köhne <c.koehne@beckhoff.com>
+ */
+
+#pragma once
+
+#include <contrib/dev/acpica/include/acpi.h>
+
+#define BHYVE_ACPI_BASE 0xf2400
+
+#define BASL_TABLE_ALIGNMENT 0x10
+#define BASL_TABLE_ALIGNMENT_FACS 0x40
+
+#define BASL_EXEC(x) \
+ do { \
+ const int error = (x); \
+ if (error) { \
+ warnc(error, \
+ "BASL failed @ %s:%d\n Failed to execute %s", \
+ __func__, __LINE__, #x); \
+ return (error); \
+ } \
+ } while (0)
+
+#define QEMU_FWCFG_MAX_NAME 56
+
+struct basl_table;
+
+int basl_finish(void);
+int basl_init(void);
+int basl_table_append_bytes(struct basl_table *table, const void *bytes,
+ uint32_t len);
+int basl_table_create(struct basl_table **table, struct vmctx *ctx,
+ const uint8_t *name, uint32_t alignment, uint32_t off);
diff --git a/usr.sbin/bhyve/basl.c b/usr.sbin/bhyve/basl.c
new file mode 100644
--- /dev/null
+++ b/usr.sbin/bhyve/basl.c
@@ -0,0 +1,139 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 Beckhoff Automation GmbH & Co. KG
+ */
+
+#include <sys/param.h>
+#include <sys/endian.h>
+#include <sys/errno.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
+
+#include <machine/vmm.h>
+
+#include <assert.h>
+#include <err.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <vmmapi.h>
+
+#include "basl.h"
+
+struct basl_table {
+ STAILQ_ENTRY(basl_table) chain;
+ struct vmctx *ctx;
+ uint8_t fwcfg_name[QEMU_FWCFG_MAX_NAME];
+ void *data;
+ uint32_t len;
+ uint32_t off;
+ uint32_t alignment;
+};
+static STAILQ_HEAD(basl_table_list, basl_table) basl_tables = STAILQ_HEAD_INITIALIZER(
+ basl_tables);
+
+static int
+basl_finish_install_guest_tables(struct basl_table *const table)
+{
+ void *gva;
+
+ /*
+ * Some guests are searching for ACPI tables in the guest memory and
+ * install them as they are. Therefore, copy the tables into the guest
+ * memory.
+ */
+ vm_map_gpa(table->ctx, BHYVE_ACPI_BASE + table->off, table->len);
+ if (gva == NULL) {
+ warnx("%s: could not map gpa [ 0x%16lx, 0x%16lx ]", __func__,
+ (uint64_t)BHYVE_ACPI_BASE + table->off,
+ (uint64_t)BHYVE_ACPI_BASE + table->off + table->len);
+ return (ENOMEM);
+ }
+ memcpy(gva, table->data, table->len);
+
+ return (0);
+}
+
+int
+basl_finish(void)
+{
+ struct basl_table *table;
+
+ if (STAILQ_EMPTY(&basl_tables)) {
+ warnx("%s: no ACPI tables found", __func__);
+ return (EINVAL);
+ }
+
+ STAILQ_FOREACH(table, &basl_tables, chain) {
+ BASL_EXEC(basl_finish_install_guest_tables(table));
+ }
+
+ return (0);
+}
+
+int
+basl_init(void)
+{
+ return (0);
+}
+
+int
+basl_table_append_bytes(struct basl_table *const table, const void *const bytes,
+ const uint32_t len)
+{
+ void *end;
+
+ assert(table != NULL);
+ assert(bytes != NULL);
+
+ if (table->len + len <= table->len) {
+ warnx("%s: table too large (table->len 0x%8x len 0x%8x)",
+ __func__, table->len, len);
+ return (EFAULT);
+ }
+
+ table->data = reallocf(table->data, table->len + len);
+ if (table->data == NULL) {
+ warnx("%s: failed to realloc table to length 0x%8x", __func__,
+ table->len + len);
+ table->len = 0;
+ return (ENOMEM);
+ }
+
+ end = (uint8_t *)table->data + table->len;
+ table->len += len;
+
+ memcpy(end, bytes, len);
+
+ return (0);
+}
+
+int
+basl_table_create(struct basl_table **const table, struct vmctx *ctx,
+ const uint8_t *const name, const uint32_t alignment,
+ const uint32_t off)
+{
+ struct basl_table *new_table;
+
+ assert(table != NULL);
+
+ new_table = calloc(1, sizeof(struct basl_table));
+ if (new_table == NULL) {
+ warnx("%s: failed to allocate table", __func__);
+ return (ENOMEM);
+ }
+
+ new_table->ctx = ctx;
+
+ snprintf(new_table->fwcfg_name, sizeof(new_table->fwcfg_name),
+ "etc/acpi/%s", name);
+
+ new_table->alignment = alignment;
+ new_table->off = off;
+
+ STAILQ_INSERT_TAIL(&basl_tables, new_table, chain);
+
+ *table = new_table;
+
+ return (0);
+}

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 16, 3:34 AM (9 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14652534
Default Alt Text
D36984.id112907.diff (5 KB)

Event Timeline