diff options
Diffstat (limited to 'src/soc/intel/fsp_broadwell_de/ramstage.c')
-rw-r--r-- | src/soc/intel/fsp_broadwell_de/ramstage.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/soc/intel/fsp_broadwell_de/ramstage.c b/src/soc/intel/fsp_broadwell_de/ramstage.c index 96b3888d0b..fd5a0392ff 100644 --- a/src/soc/intel/fsp_broadwell_de/ramstage.c +++ b/src/soc/intel/fsp_broadwell_de/ramstage.c @@ -28,6 +28,7 @@ #include <soc/pattrs.h> #include <soc/pci_devs.h> #include <soc/ramstage.h> +#include <soc/broadwell_de.h> /* Global PATTRS */ DEFINE_PATTRS; @@ -82,3 +83,47 @@ void broadwell_de_init_pre_device(void) { fill_in_pattrs(); } + +/* + * Set DPR region. + */ +void broadwell_de_set_dpr(const uintptr_t addr, const size_t size) +{ + struct device *dev; + uint32_t dpr_reg; + /* + * DMA Protected Range can be reserved below TSEG for PCODE patch + * or TXT/BootGuard related data. Rather than reporting a base address + * the DPR register reports the TOP of the region, which is the same + * as TSEG base. The region size is reported in MiB in bits 11:4. + */ + dev = pcidev_on_root(VTD_DEV, VTD_FUNC); + dpr_reg = pci_read_config32(dev, IIO_LTDPR); + if (dpr_reg & DPR_LOCK) { + printk(BIOS_ERR, "ERROR: HOSTBRIDGE[DPR] is already locked\n"); + return; + } + + dpr_reg &= ~(DPR_ADDR_MASK | DPR_SIZE_MASK); + dpr_reg |= addr & DPR_ADDR_MASK; + dpr_reg |= (size >> (20 - DPR_SIZE_SHIFT)) & DPR_SIZE_MASK; + dpr_reg |= DPR_EPM; + pci_write_config32(dev, IIO_LTDPR, dpr_reg); +} + +/* + * Lock DPR register. + */ +void broadwell_de_lock_dpr(void) +{ + struct device *dev; + uint32_t dpr_reg; + dev = pcidev_on_root(VTD_DEV, VTD_FUNC); + dpr_reg = pci_read_config32(dev, IIO_LTDPR); + if (dpr_reg & DPR_LOCK) { + printk(BIOS_ERR, "ERROR: HOSTBRIDGE[DPR] is already locked\n"); + return; + } + dpr_reg |= DPR_LOCK; + pci_write_config32(dev, IIO_LTDPR, dpr_reg); +} |