Messages in this thread Patch in this message | | | From | Yazen Ghannam <> | Subject | [PATCH 01/25] x86/MCE/AMD: Don't use naked values for DF registers | Date | Fri, 7 May 2021 15:01:16 -0400 |
| |
From: Yazen Ghannam <yazen.ghannam@amd.com>
AMD Data Fabric registers are defined using a combination of PCI function number and offset. Define a struct to hold these values, and update the DF Indirect Access function to accept a struct of this type.
Update the address translation code to include a list of the needed DF registers using this new format. Define an enumeration to give the registers more human-readable names.
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com> --- arch/x86/include/asm/amd_nb.h | 7 ++++- arch/x86/kernel/amd_nb.c | 6 ++--- arch/x86/kernel/cpu/mce/amd.c | 51 ++++++++++++++++++++++++++++------- 3 files changed, 50 insertions(+), 14 deletions(-)
diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h index 455066a06f60..a5644c119317 100644 --- a/arch/x86/include/asm/amd_nb.h +++ b/arch/x86/include/asm/amd_nb.h @@ -22,9 +22,14 @@ extern int amd_numa_init(void); extern int amd_get_subcaches(int); extern int amd_set_subcaches(int, unsigned long); +struct df_reg { + u8 func; + u16 offset; +}; + extern int amd_smn_read(u16 node, u32 address, u32 *value); extern int amd_smn_write(u16 node, u32 address, u32 value); -extern int amd_df_indirect_read(u16 node, u8 func, u16 reg, u8 instance_id, u32 *lo); +extern int amd_df_indirect_read(u16 node, struct df_reg reg, u8 instance_id, u32 *lo); struct amd_l3_cache { unsigned indices; diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index 09083094eb57..f06924093ae4 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -184,7 +184,7 @@ EXPORT_SYMBOL_GPL(amd_smn_write); * Fabric Indirect Configuration Access Data (FICAD): There are FICAD LO * and FICAD HI registers but so far we only need the LO register. */ -int amd_df_indirect_read(u16 node, u8 func, u16 reg, u8 instance_id, u32 *lo) +int amd_df_indirect_read(u16 node, struct df_reg reg, u8 instance_id, u32 *lo) { struct pci_dev *F4; u32 ficaa; @@ -198,8 +198,8 @@ int amd_df_indirect_read(u16 node, u8 func, u16 reg, u8 instance_id, u32 *lo) goto out; ficaa = 1; - ficaa |= reg & 0x3FC; - ficaa |= (func & 0x7) << 11; + ficaa |= reg.offset & 0x3FC; + ficaa |= (reg.func & 0x7) << 11; ficaa |= instance_id << 16; mutex_lock(&smn_mutex); diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c index e486f96b3cb3..1b459c143886 100644 --- a/arch/x86/kernel/cpu/mce/amd.c +++ b/arch/x86/kernel/cpu/mce/amd.c @@ -675,6 +675,37 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) deferred_error_interrupt_enable(c); } +enum df_reg_names { + /* Function 0 */ + FAB_BLK_INST_INFO_3, + DRAM_HOLE_CTL, + DRAM_BASE_ADDR_0, + DRAM_LIMIT_ADDR_0, + DRAM_BASE_ADDR_1, + DRAM_LIMIT_ADDR_1, + DRAM_OFFSET, + + /* Function 1 */ + SYS_FAB_ID_MASK, +}; + +static struct df_reg df_regs[] = { + /* D18F0x50 (FabricBlockInstanceInformation3_CS) */ + [FAB_BLK_INST_INFO_3] = {0, 0x50}, + /* D18F0x104 (DramHoleControl) */ + [DRAM_HOLE_CTL] = {0, 0x104}, + /* D18F0x110 (DramBaseAddress) */ + [DRAM_BASE_ADDR_0] = {0, 0x110}, + /* D18F0x114 (DramLimitAddress) */ + [DRAM_LIMIT_ADDR_0] = {0, 0x114}, + [DRAM_BASE_ADDR_1] = {0, 0x118}, + [DRAM_LIMIT_ADDR_1] = {0, 0x11C}, + /* D18F0x1B4 (DramOffset) */ + [DRAM_OFFSET] = {0, 0x1B4}, + /* D18F1x208 (SystemFabricIdMask) */ + [SYS_FAB_ID_MASK] = {1, 0x208}, +}; + 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; @@ -691,8 +722,9 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) u8 cs_mask, cs_id = 0; bool hash_enabled = false; - /* Read D18F0x1B4 (DramOffset), check if base 1 is used. */ - if (amd_df_indirect_read(nid, 0, 0x1B4, umc, &tmp)) + struct df_reg reg; + + if (amd_df_indirect_read(nid, df_regs[DRAM_OFFSET], umc, &tmp)) goto out_err; /* Remove HiAddrOffset from normalized address, if enabled: */ @@ -705,8 +737,8 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) } } - /* Read D18F0x110 (DramBaseAddress). */ - if (amd_df_indirect_read(nid, 0, 0x110 + (8 * base), umc, &tmp)) + reg = base ? df_regs[DRAM_BASE_ADDR_1] : df_regs[DRAM_BASE_ADDR_0]; + if (amd_df_indirect_read(nid, reg, umc, &tmp)) goto out_err; /* Check if address range is valid. */ @@ -728,8 +760,8 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) goto out_err; } - /* Read D18F0x114 (DramLimitAddress). */ - if (amd_df_indirect_read(nid, 0, 0x114 + (8 * base), umc, &tmp)) + reg = base ? df_regs[DRAM_LIMIT_ADDR_1] : df_regs[DRAM_LIMIT_ADDR_0]; + if (amd_df_indirect_read(nid, reg, umc, &tmp)) goto out_err; intlv_num_sockets = (tmp >> 8) & 0x1; @@ -785,7 +817,7 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) * umc/channel# as instance id of the coherent slave * for FICAA. */ - if (amd_df_indirect_read(nid, 0, 0x50, umc, &tmp)) + if (amd_df_indirect_read(nid, df_regs[FAB_BLK_INST_INFO_3], umc, &tmp)) goto out_err; cs_fabric_id = (tmp >> 8) & 0xFF; @@ -800,9 +832,8 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) sock_id_bit = die_id_bit; - /* Read D18F1x208 (SystemFabricIdMask). */ if (intlv_num_dies || intlv_num_sockets) - if (amd_df_indirect_read(nid, 1, 0x208, umc, &tmp)) + if (amd_df_indirect_read(nid, df_regs[SYS_FAB_ID_MASK], umc, &tmp)) goto out_err; /* If interleaved over more than 1 die. */ @@ -841,7 +872,7 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) /* If legacy MMIO hole enabled */ if (lgcy_mmio_hole_en) { - if (amd_df_indirect_read(nid, 0, 0x104, umc, &tmp)) + if (amd_df_indirect_read(nid, df_regs[DRAM_HOLE_CTL], umc, &tmp)) goto out_err; dram_hole_base = tmp & GENMASK(31, 24); -- 2.25.1
| |