diff --git a/usr.sbin/bhyve/basl.h b/usr.sbin/bhyve/basl.h
--- a/usr.sbin/bhyve/basl.h
+++ b/usr.sbin/bhyve/basl.h
@@ -49,5 +49,7 @@
     uint64_t address);
 int basl_table_append_int(struct basl_table *table, uint64_t val, uint8_t size);
 int basl_table_append_length(struct basl_table *table, uint8_t size);
+int basl_table_append_pointer(struct basl_table *table,
+    const uint8_t src_sign[ACPI_NAMESEG_SIZE], uint8_t size);
 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
--- a/usr.sbin/bhyve/basl.c
+++ b/usr.sbin/bhyve/basl.c
@@ -36,6 +36,13 @@
 	uint8_t size;
 };
 
+struct basl_table_pointer {
+	STAILQ_ENTRY(basl_table_pointer) chain;
+	uint8_t src_sign[ACPI_NAMESEG_SIZE];
+	uint32_t off;
+	uint8_t size;
+};
+
 struct basl_table {
 	STAILQ_ENTRY(basl_table) chain;
 	struct vmctx *ctx;
@@ -47,6 +54,7 @@
 	STAILQ_HEAD(basl_table_checksum_list,
 	    basl_table_checksum) checksums;
 	STAILQ_HEAD(basl_table_length_list, basl_table_length) lengths;
+	STAILQ_HEAD(basl_table_pointer_list, basl_table_pointer) pointers;
 };
 static STAILQ_HEAD(basl_table_list, basl_table) basl_tables = STAILQ_HEAD_INITIALIZER(
     basl_tables);
@@ -183,6 +191,101 @@
 	return (0);
 }
 
+static struct basl_table *
+basl_get_table_by_sign(const uint8_t sign[ACPI_NAMESEG_SIZE])
+{
+	struct basl_table *table;
+	STAILQ_FOREACH(table, &basl_tables, chain) {
+		const ACPI_TABLE_HEADER *const header =
+		    (const ACPI_TABLE_HEADER *)table->data;
+		if (strncmp(header->Signature, sign,
+			sizeof(header->Signature)) == 0) {
+			return (table);
+		}
+	}
+
+	warnx("%s: %c%c%c%c not found", __func__, sign[0], sign[1], sign[2],
+	    sign[3]);
+	return (NULL);
+}
+
+static int
+basl_finish_patch_pointers(struct basl_table *const table)
+{
+	struct basl_table_pointer *pointer;
+	STAILQ_FOREACH(pointer, &table->pointers, chain) {
+		assert(pointer->off < table->len);
+		assert(pointer->off + pointer->size <= table->len);
+
+		const struct basl_table *const src_table =
+		    basl_get_table_by_sign(pointer->src_sign);
+		if (src_table == NULL) {
+			warnx("%s: could not find ACPI table %c%c%c%c",
+			    __func__, pointer->src_sign[0],
+			    pointer->src_sign[1], pointer->src_sign[2],
+			    pointer->src_sign[3]);
+			return (EFAULT);
+		}
+
+		/*
+		 * Guest bios versions without qemu fwcfg support search for
+		 * ACPI tables in the guest memory and install them as is.
+		 * Therefore, patch the pointers in the guest memory copies
+		 * manually.
+		 */
+		const uint64_t gpa = BHYVE_ACPI_BASE + table->off;
+		if (gpa < BHYVE_ACPI_BASE) {
+			warnx("%s: table offset of 0x%8x is too large",
+			    __func__, table->off);
+			return (EFAULT);
+		}
+
+		uint8_t *const gva = vm_map_gpa(table->ctx, gpa, table->len);
+		if (gva == NULL) {
+			warnx("%s: could not map gpa [ 0x%16lx, 0x%16lx ]",
+			    __func__, gpa, gpa + table->len);
+			return (ENOMEM);
+		}
+
+		/*
+		 * ACPI tables are always little endian. So, memcpy works here
+		 * for fetching the current value.
+		 */
+		uint64_t val_le = 0;
+		memcpy(&val_le, gva + pointer->off, pointer->size);
+
+		uint64_t val;
+		switch (pointer->size) {
+		case 1:
+			val = val_le;
+			break;
+		case 2:
+			val = le16toh(val_le);
+			break;
+		case 4:
+			val = le32toh(val_le);
+			break;
+		case 8:
+			val = le64toh(val_le);
+			break;
+		default:
+			warnx("%s: invalid pointer size %x", __func__,
+			    pointer->size);
+			return (EINVAL);
+		}
+		val += BHYVE_ACPI_BASE + src_table->off;
+
+		/*
+		 * ACPI tables are always little endian. So, memcpy works here
+		 * for writing the new value.
+		 */
+		val_le = htole64(val);
+		memcpy(gva + pointer->off, &val_le, pointer->size);
+	}
+
+	return (0);
+}
+
 static int
 basl_finish_set_length(struct basl_table *const table)
 {
@@ -217,6 +320,7 @@
 		BASL_EXEC(basl_finish_install_guest_tables(table));
 	}
 	STAILQ_FOREACH(table, &basl_tables, chain) {
+		BASL_EXEC(basl_finish_patch_pointers(table));
 		/*
 		 * Calculate the checksum as last step!
 		 */
@@ -271,6 +375,27 @@
 	return (0);
 }
 
+static int
+basl_table_add_pointer(struct basl_table *const table,
+    const uint8_t src_sign[ACPI_NAMESEG_SIZE], const uint32_t off,
+    const uint8_t size)
+{
+	struct basl_table_pointer *const pointer = calloc(1,
+	    sizeof(struct basl_table_pointer));
+	if (pointer == NULL) {
+		warnx("%s: failed to allocate pointer", __func__);
+		return (ENOMEM);
+	}
+
+	memcpy(pointer->src_sign, src_sign, sizeof(pointer->src_sign));
+	pointer->off = off;
+	pointer->size = size;
+
+	STAILQ_INSERT_TAIL(&table->pointers, pointer, chain);
+
+	return (0);
+}
+
 int
 basl_table_append_bytes(struct basl_table *const table, const void *const bytes,
     const uint32_t len)
@@ -349,6 +474,19 @@
 	return (0);
 }
 
+int
+basl_table_append_pointer(struct basl_table *const table,
+    const uint8_t src_sign[ACPI_NAMESEG_SIZE], const uint8_t size)
+{
+	assert(table != NULL);
+	assert(size <= sizeof(UINT64));
+
+	BASL_EXEC(basl_table_add_pointer(table, src_sign, table->len, size));
+	BASL_EXEC(basl_table_append_int(table, 0, size));
+
+	return (0);
+}
+
 int
 basl_table_create(struct basl_table **const table, struct vmctx *ctx,
     const uint8_t *const name, const uint32_t alignment,
@@ -374,6 +512,7 @@
 
 	STAILQ_INIT(&new_table->checksums);
 	STAILQ_INIT(&new_table->lengths);
+	STAILQ_INIT(&new_table->pointers);
 
 	STAILQ_INSERT_TAIL(&basl_tables, new_table, chain);