EDAC/amd64: Adjust address translation for Hygon family 18h model 4h
Add Hygon family 18h model 4h processor support for DramOffset and HiAddrOffset, and get the socket interleaving number from DramBase- Address(D18F0x110). Update intlv_num_chan and num_intlv_bits support for Hygon family 18h model 4h processor. Signed-off-by: Pu Wen <puwen@hygon.cn> Signed-off-by: Jinliang Zheng <alexjlzheng@tencent.com> Reviewed-by: Bin Lai <robinlai@tencent.com> Signed-off-by: Jinliang Zheng <alexjlzheng@tencent.com> Reviewed-by: caelli <caelli@tencent.com> Signed-off-by: Jianping Liu <frankjpliu@tencent.com>
This commit is contained in:
parent
36d1aba7a1
commit
2c453f4b4e
|
@ -713,13 +713,21 @@ 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))
|
||||
/* Read DramOffset, check if base 1 is used. */
|
||||
if (hygon_f18h_m4h() &&
|
||||
amd_df_indirect_read(nid, 0, 0x214, umc, &tmp))
|
||||
goto out_err;
|
||||
else if (amd_df_indirect_read(nid, 0, 0x1B4, umc, &tmp))
|
||||
goto out_err;
|
||||
|
||||
/* Remove HiAddrOffset from normalized address, if enabled: */
|
||||
if (tmp & BIT(0)) {
|
||||
u64 hi_addr_offset = (tmp & GENMASK_ULL(31, 20)) << 8;
|
||||
u64 hi_addr_offset;
|
||||
|
||||
if (hygon_f18h_m4h())
|
||||
hi_addr_offset = (tmp & GENMASK_ULL(31, 18)) << 8;
|
||||
else
|
||||
hi_addr_offset = (tmp & GENMASK_ULL(31, 20)) << 8;
|
||||
|
||||
if (norm_addr >= hi_addr_offset) {
|
||||
ret_addr -= hi_addr_offset;
|
||||
|
@ -738,6 +746,9 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr)
|
|||
goto out_err;
|
||||
}
|
||||
|
||||
intlv_num_sockets = 0;
|
||||
if (hygon_f18h_m4h())
|
||||
intlv_num_sockets = (tmp >> 2) & 0x3;
|
||||
lgcy_mmio_hole_en = tmp & BIT(1);
|
||||
intlv_num_chan = (tmp >> 4) & 0xF;
|
||||
intlv_addr_sel = (tmp >> 8) & 0x7;
|
||||
|
@ -754,7 +765,8 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr)
|
|||
if (amd_df_indirect_read(nid, 0, 0x114 + (8 * base), umc, &tmp))
|
||||
goto out_err;
|
||||
|
||||
intlv_num_sockets = (tmp >> 8) & 0x1;
|
||||
if (!hygon_f18h_m4h())
|
||||
intlv_num_sockets = (tmp >> 8) & 0x1;
|
||||
intlv_num_dies = (tmp >> 10) & 0x3;
|
||||
dram_limit_addr = ((tmp & GENMASK_ULL(31, 12)) << 16) | GENMASK_ULL(27, 0);
|
||||
|
||||
|
@ -764,6 +776,10 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr)
|
|||
switch (intlv_num_chan) {
|
||||
case 0: intlv_num_chan = 0; break;
|
||||
case 1: intlv_num_chan = 1; break;
|
||||
case 2:
|
||||
if (hygon_f18h_m4h())
|
||||
intlv_num_chan = 2;
|
||||
break;
|
||||
case 3: intlv_num_chan = 2; break;
|
||||
case 5: intlv_num_chan = 3; break;
|
||||
case 7: intlv_num_chan = 4; break;
|
||||
|
@ -790,8 +806,9 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr)
|
|||
/* Add a bit if sockets are interleaved. */
|
||||
num_intlv_bits += intlv_num_sockets;
|
||||
|
||||
/* Assert num_intlv_bits <= 4 */
|
||||
if (num_intlv_bits > 4) {
|
||||
/* Assert num_intlv_bits in the correct range. */
|
||||
if ((hygon_f18h_m4h() && num_intlv_bits > 7) ||
|
||||
(!hygon_f18h_m4h() && num_intlv_bits > 4)) {
|
||||
pr_err("%s: Invalid interleave bits %d.\n",
|
||||
__func__, num_intlv_bits);
|
||||
goto out_err;
|
||||
|
@ -810,7 +827,10 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr)
|
|||
if (amd_df_indirect_read(nid, 0, 0x50, umc, &tmp))
|
||||
goto out_err;
|
||||
|
||||
cs_fabric_id = (tmp >> 8) & 0xFF;
|
||||
if (hygon_f18h_m4h())
|
||||
cs_fabric_id = (tmp >> 8) & 0x7FF;
|
||||
else
|
||||
cs_fabric_id = (tmp >> 8) & 0xFF;
|
||||
die_id_bit = 0;
|
||||
|
||||
/* If interleaved over more than 1 channel: */
|
||||
|
@ -830,8 +850,13 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr)
|
|||
/* If interleaved over more than 1 die. */
|
||||
if (intlv_num_dies) {
|
||||
sock_id_bit = die_id_bit + intlv_num_dies;
|
||||
die_id_shift = (tmp >> 24) & 0xF;
|
||||
die_id_mask = (tmp >> 8) & 0xFF;
|
||||
if (hygon_f18h_m4h()) {
|
||||
die_id_shift = (tmp >> 12) & 0xF;
|
||||
die_id_mask = tmp & 0x7FF;
|
||||
} else {
|
||||
die_id_shift = (tmp >> 24) & 0xF;
|
||||
die_id_mask = (tmp >> 8) & 0xFF;
|
||||
}
|
||||
|
||||
cs_id |= ((cs_fabric_id & die_id_mask) >> die_id_shift) << die_id_bit;
|
||||
}
|
||||
|
@ -839,7 +864,10 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr)
|
|||
/* If interleaved over more than 1 socket. */
|
||||
if (intlv_num_sockets) {
|
||||
socket_id_shift = (tmp >> 28) & 0xF;
|
||||
socket_id_mask = (tmp >> 16) & 0xFF;
|
||||
if (hygon_f18h_m4h())
|
||||
socket_id_mask = (tmp >> 16) & 0x7FF;
|
||||
else
|
||||
socket_id_mask = (tmp >> 16) & 0xFF;
|
||||
|
||||
cs_id |= ((cs_fabric_id & socket_id_mask) >> socket_id_shift) << sock_id_bit;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue