I think those global variables are unnecessary. Please see the comment on 4/4. thanks, On Sat, Aug 28, 2010 at 06:02:57PM +0300, Eduard - Gabriel Munteanu wrote: > The AMD IOMMU must be discovered and initialized by the BIOS if present. > > Signed-off-by: Eduard - Gabriel Munteanu <eduard.munteanu@xxxxxxxxxxx> > --- > 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@xxxxxxxxxxx> > +// > +// 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 > > > _______________________________________________ > SeaBIOS mailing list > SeaBIOS@xxxxxxxxxxx > http://www.seabios.org/mailman/listinfo/seabios > -- yamahata -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html