[SeaBIOS] [PATCH 3/4] iommu: introduce AMD IOMMU support, initialize it
Eduard - Gabriel Munteanu
eduard.munteanu at linux360.ro
Sat Aug 28 17:02:57 CEST 2010
The AMD IOMMU must be discovered and initialized by the BIOS if present.
Signed-off-by: Eduard - Gabriel Munteanu <eduard.munteanu at linux360.ro>
---
Makefile | 2 +-
src/iommu.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/iommu.h | 12 ++++++++++
src/pci_ids.h | 1 +
src/pci_regs.h | 1 +
src/pciinit.c | 15 +++++++++++++
6 files changed, 93 insertions(+), 1 deletions(-)
create mode 100644 src/iommu.c
create mode 100644 src/iommu.h
diff --git a/Makefile b/Makefile
index 47f5625..cee286a 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@ SRCBOTH=misc.c pmm.c stacks.c output.c util.c block.c floppy.c ata.c mouse.c \
kbd.c pci.c serial.c clock.c pic.c cdrom.c ps2port.c smp.c resume.c \
pnpbios.c pirtable.c vgahooks.c ramdisk.c pcibios.c blockcmd.c \
usb.c usb-uhci.c usb-ohci.c usb-ehci.c usb-hid.c usb-msc.c \
- virtio-ring.c virtio-pci.c virtio-blk.c
+ virtio-ring.c virtio-pci.c virtio-blk.c iommu.c
SRC16=$(SRCBOTH) system.c disk.c apm.c font.c
SRC32FLAT=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \
acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c \
diff --git a/src/iommu.c b/src/iommu.c
new file mode 100644
index 0000000..4ff62fc
--- /dev/null
+++ b/src/iommu.c
@@ -0,0 +1,63 @@
+// AMD IOMMU initialization code.
+//
+// Copyright (C) 2010 Eduard - Gabriel Munteanu <eduard.munteanu at linux360.ro>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "iommu.h"
+#include "pci.h"
+#include "types.h"
+
+#define IOMMU_CAP_BAR_LOW 0x04
+#define IOMMU_CAP_BAR_HIGH 0x08
+#define IOMMU_CAP_RANGE 0x0C
+#define IOMMU_CAP_MISC 0x10
+
+static int iommu_bdf = -1;
+static u8 iommu_cap_offset;
+static u32 iommu_base;
+
+void iommu_init(int bdf, u32 base)
+{
+ u8 ptr, cap, type;
+
+ /* Only one IOMMU is supported. */
+ if (iommu_bdf >= 0)
+ return;
+
+ foreachcap(bdf, ptr, cap) {
+ type = pci_config_readb(bdf, cap);
+ if (type == PCI_CAP_ID_SEC)
+ break;
+ }
+ if (!cap)
+ return;
+
+ pci_config_writel(bdf, cap + IOMMU_CAP_RANGE, 0);
+ pci_config_writel(bdf, cap + IOMMU_CAP_BAR_HIGH, 0);
+ pci_config_writel(bdf, cap + IOMMU_CAP_BAR_LOW, base | 1);
+
+ iommu_bdf = bdf;
+ iommu_cap_offset = cap;
+ iommu_base = base;
+}
+
+int iommu_get_bdf(void)
+{
+ return iommu_bdf;
+}
+
+u8 iommu_get_cap_offset(void)
+{
+ return iommu_cap_offset;
+}
+
+u32 iommu_get_misc(void)
+{
+ return pci_config_readw(iommu_bdf, iommu_cap_offset + IOMMU_CAP_MISC + 2);
+}
+
+u32 iommu_get_base(void)
+{
+ return iommu_base;
+}
diff --git a/src/iommu.h b/src/iommu.h
new file mode 100644
index 0000000..27ae2c7
--- /dev/null
+++ b/src/iommu.h
@@ -0,0 +1,12 @@
+#ifndef __IOMMU_H
+#define __IOMMU_H
+
+#include "types.h"
+
+void iommu_init(int bdf, u32 base);
+int iommu_get_bdf(void);
+u8 iommu_get_cap_offset(void);
+u32 iommu_get_misc(void);
+u32 iommu_get_base(void);
+
+#endif // __IOMMU_H
diff --git a/src/pci_ids.h b/src/pci_ids.h
index 441c086..6876fbe 100644
--- a/src/pci_ids.h
+++ b/src/pci_ids.h
@@ -72,6 +72,7 @@
#define PCI_CLASS_SYSTEM_RTC 0x0803
#define PCI_CLASS_SYSTEM_PCI_HOTPLUG 0x0804
#define PCI_CLASS_SYSTEM_SDHCI 0x0805
+#define PCI_CLASS_SYSTEM_IOMMU 0x0806
#define PCI_CLASS_SYSTEM_OTHER 0x0880
#define PCI_BASE_CLASS_INPUT 0x09
diff --git a/src/pci_regs.h b/src/pci_regs.h
index e6180ce..46b048f 100644
--- a/src/pci_regs.h
+++ b/src/pci_regs.h
@@ -208,6 +208,7 @@
#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */
#define PCI_CAP_ID_SSVID 0x0D /* Bridge subsystem vendor/device ID */
#define PCI_CAP_ID_AGP3 0x0E /* AGP Target PCI-PCI bridge */
+#define PCI_CAP_ID_SEC 0x0F /* Secure Device (AMD IOMMU) */
#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
diff --git a/src/pciinit.c b/src/pciinit.c
index f75e552..7cb67c6 100644
--- a/src/pciinit.c
+++ b/src/pciinit.c
@@ -11,6 +11,7 @@
#include "pci_ids.h" // PCI_VENDOR_ID_INTEL
#include "pci_regs.h" // PCI_COMMAND
#include "dev-i440fx.h"
+#include "iommu.h"
#define PCI_ROM_SLOT 6
#define PCI_NUM_REGIONS 7
@@ -262,6 +263,16 @@ static void apple_macio_init(u16 bdf, void *arg)
pci_set_io_region_addr(bdf, 0, 0x80800000);
}
+static void pci_bios_init_iommu(u16 bdf, void *arg)
+{
+ u32 base;
+
+ base = ALIGN(pci_bios_mem_addr, 0x4000);
+ pci_bios_mem_addr += 0x4000;
+
+ iommu_init(bdf, base);
+}
+
static const struct pci_device_id pci_class_tbl[] = {
/* STORAGE IDE */
PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1,
@@ -285,6 +296,10 @@ static const struct pci_device_id pci_class_tbl[] = {
PCI_DEVICE_CLASS(PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_BRIDGE_PCI,
pci_bios_init_device_bridge),
+ /* AMD IOMMU */
+ PCI_DEVICE_CLASS(PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_SYSTEM_IOMMU,
+ pci_bios_init_iommu),
+
/* default */
PCI_DEVICE(PCI_ANY_ID, PCI_ANY_ID, pci_bios_allocate_regions),
--
1.7.1
More information about the SeaBIOS
mailing list