summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/acpi/acpi_dmar.c20
-rw-r--r--src/include/acpi/acpi.h4
2 files changed, 22 insertions, 2 deletions
diff --git a/src/acpi/acpi_dmar.c b/src/acpi/acpi_dmar.c
index 20a100d337..67bca5592d 100644
--- a/src/acpi/acpi_dmar.c
+++ b/src/acpi/acpi_dmar.c
@@ -2,7 +2,9 @@
#include <acpi/acpi.h>
#include <arch/ioapic.h>
+#include <assert.h>
#include <cpu/cpu.h>
+#include <lib.h>
#include <version.h>
void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags,
@@ -37,8 +39,23 @@ void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags,
}
unsigned long acpi_create_dmar_drhd_4k(unsigned long current, u8 flags,
- u16 segment, u64 bar)
+ u16 segment, u64 bar)
{
+ return acpi_create_dmar_drhd(current, flags, segment, bar, 4 * KiB);
+}
+
+unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags,
+ u16 segment, u64 bar, size_t size)
+{
+ /*
+ * Refer to IntelĀ® Virtualization Technology for Directed I/O
+ * Architecture Specification Revision 4.1,
+ * size is at least 1 page and max 2^15 pages, 4 KiB each, and the bar
+ * should be aligned with size.
+ */
+ assert(4 * KiB <= size && size <= (1 << 15) * 4 * KiB && IS_POWER_OF_2(size));
+ assert(IS_ALIGNED(bar, size));
+
dmar_entry_t *drhd = (dmar_entry_t *)current;
memset(drhd, 0, sizeof(*drhd));
drhd->type = DMAR_DRHD;
@@ -46,6 +63,7 @@ unsigned long acpi_create_dmar_drhd_4k(unsigned long current, u8 flags,
drhd->flags = flags;
drhd->segment = segment;
drhd->bar = bar;
+ drhd->size = log2_64(size) - 12;
return drhd->length;
}
diff --git a/src/include/acpi/acpi.h b/src/include/acpi/acpi.h
index 469d672f41..a36e65c9d9 100644
--- a/src/include/acpi/acpi.h
+++ b/src/include/acpi/acpi.h
@@ -638,7 +638,7 @@ typedef struct dmar_entry {
u16 type;
u16 length;
u8 flags;
- u8 reserved;
+ u8 size;
u16 segment;
u64 bar;
} __packed dmar_entry_t;
@@ -1851,6 +1851,8 @@ void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags,
unsigned long (*acpi_fill_dmar)(unsigned long));
unsigned long acpi_create_dmar_drhd_4k(unsigned long current, u8 flags,
u16 segment, u64 bar);
+unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags,
+ u16 segment, u64 bar, size_t size);
unsigned long acpi_create_dmar_rmrr(unsigned long current, u16 segment,
u64 bar, u64 limit);
unsigned long acpi_create_dmar_atsr(unsigned long current, u8 flags,