soc/intel/fsp_broadwell_de: Add function to set DPR

Add code for FSP Broadwell DE to set the DPR.
Used by the Intel TXT code.

Tested on Intel Broadwell DE using Intel TXT.

Change-Id: Ib5e1ba8731e5cea1be9319a1fb9658dba841dc7b
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/36226
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com>
This commit is contained in:
Patrick Rudolph 2019-06-11 09:22:39 +02:00 committed by Patrick Georgi
parent 7bdedcdc33
commit 59ba0a257a
3 changed files with 56 additions and 0 deletions

View File

@ -31,6 +31,15 @@ size_t sa_get_tseg_size(void);
#define TSEG_BASE 0xa8 /* TSEG base */ #define TSEG_BASE 0xa8 /* TSEG base */
#define TSEG_LIMIT 0xac /* TSEG limit */ #define TSEG_LIMIT 0xac /* TSEG limit */
#define IIO_LTDPR 0x290
#define DPR_LOCK (1 << 0)
#define DPR_EPM (1 << 2)
#define DPR_PRS (1 << 1)
#define DPR_SIZE_MASK 0xff0
#define DPR_SIZE_SHIFT 4
#define DPR_ADDR_MASK 0xfff00000
#define DPR_ADDR_SHIFT 20
/* CPU bus clock is fixed at 100MHz */ /* CPU bus clock is fixed at 100MHz */
#define CPU_BCLK 100 #define CPU_BCLK 100

View File

@ -24,6 +24,8 @@
void broadwell_de_init_pre_device(void); void broadwell_de_init_pre_device(void);
void broadwell_de_init_cpus(struct device *dev); void broadwell_de_init_cpus(struct device *dev);
void southcluster_enable_dev(struct device *dev); void southcluster_enable_dev(struct device *dev);
void broadwell_de_set_dpr(const uintptr_t addr, const size_t size);
void broadwell_de_lock_dpr(void);
extern struct pci_operations soc_pci_ops; extern struct pci_operations soc_pci_ops;

View File

@ -28,6 +28,7 @@
#include <soc/pattrs.h> #include <soc/pattrs.h>
#include <soc/pci_devs.h> #include <soc/pci_devs.h>
#include <soc/ramstage.h> #include <soc/ramstage.h>
#include <soc/broadwell_de.h>
/* Global PATTRS */ /* Global PATTRS */
DEFINE_PATTRS; DEFINE_PATTRS;
@ -82,3 +83,47 @@ void broadwell_de_init_pre_device(void)
{ {
fill_in_pattrs(); 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);
}