diff options
Diffstat (limited to 'src/northbridge/intel/sandybridge')
-rw-r--r-- | src/northbridge/intel/sandybridge/Makefile.inc | 1 | ||||
-rw-r--r-- | src/northbridge/intel/sandybridge/early_init.c | 3 | ||||
-rw-r--r-- | src/northbridge/intel/sandybridge/iommu.c | 48 | ||||
-rw-r--r-- | src/northbridge/intel/sandybridge/northbridge.c | 7 | ||||
-rw-r--r-- | src/northbridge/intel/sandybridge/sandybridge.h | 4 |
5 files changed, 63 insertions, 0 deletions
diff --git a/src/northbridge/intel/sandybridge/Makefile.inc b/src/northbridge/intel/sandybridge/Makefile.inc index 2430b4eb89..2d68c03d87 100644 --- a/src/northbridge/intel/sandybridge/Makefile.inc +++ b/src/northbridge/intel/sandybridge/Makefile.inc @@ -34,6 +34,7 @@ romstage-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += raminit.c romstage-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += romstage.c romstage-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ../../../device/dram/ddr3.c romstage-y += mrccache.c +romstage-y += iommu.c romstage-y += early_init.c romstage-y += report_platform.c romstage-y += ../../../arch/x86/walkcbfs.S diff --git a/src/northbridge/intel/sandybridge/early_init.c b/src/northbridge/intel/sandybridge/early_init.c index b3a829d920..81bf9d5854 100644 --- a/src/northbridge/intel/sandybridge/early_init.c +++ b/src/northbridge/intel/sandybridge/early_init.c @@ -169,6 +169,9 @@ void sandybridge_early_initialization(int chipset_type) /* Setup all BARs required for early PCIe and raminit */ sandybridge_setup_bars(); + /* Setup IOMMU BARs */ + sandybridge_init_iommu(); + /* Device Enable, don't touch PEG bits */ deven = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN) | DEVEN_IGD; pci_write_config32(PCI_DEV(0, 0, 0), DEVEN, deven); diff --git a/src/northbridge/intel/sandybridge/iommu.c b/src/northbridge/intel/sandybridge/iommu.c new file mode 100644 index 0000000000..08fbe05102 --- /dev/null +++ b/src/northbridge/intel/sandybridge/iommu.c @@ -0,0 +1,48 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <stdint.h> + +#include <arch/io.h> +#include <device/device.h> +#include <device/pci_def.h> + +#include "sandybridge.h" + +void sandybridge_init_iommu(void) +{ + const u32 capid0_a = pci_read_config32(PCI_DEV(0, 0, 0), 0xe4); + if (capid0_a & (1 << 23)) + return; + + /* setup BARs */ + MCHBAR32(0x5404) = IOMMU_BASE1 >> 32; + MCHBAR32(0x5400) = IOMMU_BASE1 | 1; + MCHBAR32(0x5414) = IOMMU_BASE2 >> 32; + MCHBAR32(0x5410) = IOMMU_BASE2 | 1; + + /* lock policies */ + write32((void *)(IOMMU_BASE1 + 0xff0), 0x80000000); + + const struct device *const azalia = + dev_find_slot(0x00, PCI_DEVFN(0x1b, 0)); + if (azalia && azalia->enabled) { + write32((void *)(IOMMU_BASE2 + 0xff0), 0x20000000); + write32((void *)(IOMMU_BASE2 + 0xff0), 0xa0000000); + } else { + write32((void *)(IOMMU_BASE2 + 0xff0), 0x80000000); + } +} diff --git a/src/northbridge/intel/sandybridge/northbridge.c b/src/northbridge/intel/sandybridge/northbridge.c index 09830de102..c718353b8d 100644 --- a/src/northbridge/intel/sandybridge/northbridge.c +++ b/src/northbridge/intel/sandybridge/northbridge.c @@ -127,6 +127,13 @@ static void add_fixed_resources(struct device *dev, int index) /* Required for SandyBridge sighting 3715511 */ bad_ram_resource(dev, index++, 0x20000000 >> 10, 0x00200000 >> 10); bad_ram_resource(dev, index++, 0x40000000 >> 10, 0x00200000 >> 10); + + /* Reserve IOMMU BARs */ + const u32 capid0_a = pci_read_config32(dev, 0xe4); + if (!(capid0_a & (1 << 23))) { + mmio_resource(dev, index++, IOMMU_BASE1 >> 10, 4); + mmio_resource(dev, index++, IOMMU_BASE2 >> 10, 4); + } } static void pci_domain_set_resources(device_t dev) diff --git a/src/northbridge/intel/sandybridge/sandybridge.h b/src/northbridge/intel/sandybridge/sandybridge.h index 506e6fd6c8..853dd1c67d 100644 --- a/src/northbridge/intel/sandybridge/sandybridge.h +++ b/src/northbridge/intel/sandybridge/sandybridge.h @@ -54,6 +54,9 @@ #define DEFAULT_EPBAR 0xfed19000 /* 4 KB */ #define DEFAULT_RCBABASE ((u8 *)0xfed1c000) +#define IOMMU_BASE1 0xfed90000ULL +#define IOMMU_BASE2 0xfed91000ULL + #include <southbridge/intel/bd82x6x/pch.h> /* Everything below this line is ignored in the DSDT */ @@ -199,6 +202,7 @@ void intel_sandybridge_finalize_smm(void); #else /* !__SMM__ */ int bridge_silicon_revision(void); void sandybridge_early_initialization(int chipset_type); +void sandybridge_init_iommu(void); void sandybridge_late_initialization(void); void northbridge_romstage_finalize(int s3resume); |