Commit 448c3d60 authored by Yazen Ghannam's avatar Yazen Ghannam Committed by Borislav Petkov

EDAC/amd64: Allow for DF Indirect Broadcast reads

The DF Indirect Access method allows for "Broadcast" accesses in which
case no specific instance is targeted. Add support using a reserved
instance ID of 0xFF to indicate a broadcast access. Set the FICAA
register appropriately.

Define helpers functions for instance and broadcast reads and use them
where appropriate.

Drop the "amd_" prefix since these functions are all static.
Signed-off-by: default avatarYazen Ghannam <yazen.ghannam@amd.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20211028175728.121452-4-yazen.ghannam@amd.com
parent b3218ae4
...@@ -1000,8 +1000,11 @@ static DEFINE_MUTEX(df_indirect_mutex); ...@@ -1000,8 +1000,11 @@ static DEFINE_MUTEX(df_indirect_mutex);
* *
* Fabric Indirect Configuration Access Data (FICAD): There are FICAD LO * Fabric Indirect Configuration Access Data (FICAD): There are FICAD LO
* and FICAD HI registers but so far we only need the LO register. * and FICAD HI registers but so far we only need the LO register.
*
* Use Instance Id 0xFF to indicate a broadcast read.
*/ */
static int amd_df_indirect_read(u16 node, u8 func, u16 reg, u8 instance_id, u32 *lo) #define DF_BROADCAST 0xFF
static int __df_indirect_read(u16 node, u8 func, u16 reg, u8 instance_id, u32 *lo)
{ {
struct pci_dev *F4; struct pci_dev *F4;
u32 ficaa; u32 ficaa;
...@@ -1014,7 +1017,7 @@ static int amd_df_indirect_read(u16 node, u8 func, u16 reg, u8 instance_id, u32 ...@@ -1014,7 +1017,7 @@ static int amd_df_indirect_read(u16 node, u8 func, u16 reg, u8 instance_id, u32
if (!F4) if (!F4)
goto out; goto out;
ficaa = 1; ficaa = (instance_id == DF_BROADCAST) ? 0 : 1;
ficaa |= reg & 0x3FC; ficaa |= reg & 0x3FC;
ficaa |= (func & 0x7) << 11; ficaa |= (func & 0x7) << 11;
ficaa |= instance_id << 16; ficaa |= instance_id << 16;
...@@ -1038,6 +1041,16 @@ static int amd_df_indirect_read(u16 node, u8 func, u16 reg, u8 instance_id, u32 ...@@ -1038,6 +1041,16 @@ static int amd_df_indirect_read(u16 node, u8 func, u16 reg, u8 instance_id, u32
return err; return err;
} }
static int df_indirect_read_instance(u16 node, u8 func, u16 reg, u8 instance_id, u32 *lo)
{
return __df_indirect_read(node, func, reg, instance_id, lo);
}
static int df_indirect_read_broadcast(u16 node, u8 func, u16 reg, u32 *lo)
{
return __df_indirect_read(node, func, reg, DF_BROADCAST, lo);
}
static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr)
{ {
u64 dram_base_addr, dram_limit_addr, dram_hole_base; u64 dram_base_addr, dram_limit_addr, dram_hole_base;
...@@ -1055,7 +1068,7 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr ...@@ -1055,7 +1068,7 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr
bool hash_enabled = false; bool hash_enabled = false;
/* Read D18F0x1B4 (DramOffset), check if base 1 is used. */ /* Read D18F0x1B4 (DramOffset), check if base 1 is used. */
if (amd_df_indirect_read(nid, 0, 0x1B4, umc, &tmp)) if (df_indirect_read_instance(nid, 0, 0x1B4, umc, &tmp))
goto out_err; goto out_err;
/* Remove HiAddrOffset from normalized address, if enabled: */ /* Remove HiAddrOffset from normalized address, if enabled: */
...@@ -1069,7 +1082,7 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr ...@@ -1069,7 +1082,7 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr
} }
/* Read D18F0x110 (DramBaseAddress). */ /* Read D18F0x110 (DramBaseAddress). */
if (amd_df_indirect_read(nid, 0, 0x110 + (8 * base), umc, &tmp)) if (df_indirect_read_instance(nid, 0, 0x110 + (8 * base), umc, &tmp))
goto out_err; goto out_err;
/* Check if address range is valid. */ /* Check if address range is valid. */
...@@ -1092,7 +1105,7 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr ...@@ -1092,7 +1105,7 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr
} }
/* Read D18F0x114 (DramLimitAddress). */ /* Read D18F0x114 (DramLimitAddress). */
if (amd_df_indirect_read(nid, 0, 0x114 + (8 * base), umc, &tmp)) if (df_indirect_read_instance(nid, 0, 0x114 + (8 * base), umc, &tmp))
goto out_err; goto out_err;
intlv_num_sockets = (tmp >> 8) & 0x1; intlv_num_sockets = (tmp >> 8) & 0x1;
...@@ -1148,7 +1161,7 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr ...@@ -1148,7 +1161,7 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr
* umc/channel# as instance id of the coherent slave * umc/channel# as instance id of the coherent slave
* for FICAA. * for FICAA.
*/ */
if (amd_df_indirect_read(nid, 0, 0x50, umc, &tmp)) if (df_indirect_read_instance(nid, 0, 0x50, umc, &tmp))
goto out_err; goto out_err;
cs_fabric_id = (tmp >> 8) & 0xFF; cs_fabric_id = (tmp >> 8) & 0xFF;
...@@ -1165,7 +1178,7 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr ...@@ -1165,7 +1178,7 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr
/* Read D18F1x208 (SystemFabricIdMask). */ /* Read D18F1x208 (SystemFabricIdMask). */
if (intlv_num_dies || intlv_num_sockets) if (intlv_num_dies || intlv_num_sockets)
if (amd_df_indirect_read(nid, 1, 0x208, umc, &tmp)) if (df_indirect_read_broadcast(nid, 1, 0x208, &tmp))
goto out_err; goto out_err;
/* If interleaved over more than 1 die. */ /* If interleaved over more than 1 die. */
...@@ -1204,7 +1217,7 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr ...@@ -1204,7 +1217,7 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr
/* If legacy MMIO hole enabled */ /* If legacy MMIO hole enabled */
if (lgcy_mmio_hole_en) { if (lgcy_mmio_hole_en) {
if (amd_df_indirect_read(nid, 0, 0x104, umc, &tmp)) if (df_indirect_read_broadcast(nid, 0, 0x104, &tmp))
goto out_err; goto out_err;
dram_hole_base = tmp & GENMASK(31, 24); dram_hole_base = tmp & GENMASK(31, 24);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment