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;
|
u8 cs_mask, cs_id = 0;
|
||||||
bool hash_enabled = false;
|
bool hash_enabled = false;
|
||||||
|
|
||||||
/* Read D18F0x1B4 (DramOffset), check if base 1 is used. */
|
/* Read DramOffset, check if base 1 is used. */
|
||||||
if (amd_df_indirect_read(nid, 0, 0x1B4, umc, &tmp))
|
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;
|
goto out_err;
|
||||||
|
|
||||||
/* Remove HiAddrOffset from normalized address, if enabled: */
|
/* Remove HiAddrOffset from normalized address, if enabled: */
|
||||||
if (tmp & BIT(0)) {
|
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) {
|
if (norm_addr >= hi_addr_offset) {
|
||||||
ret_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;
|
goto out_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
intlv_num_sockets = 0;
|
||||||
|
if (hygon_f18h_m4h())
|
||||||
|
intlv_num_sockets = (tmp >> 2) & 0x3;
|
||||||
lgcy_mmio_hole_en = tmp & BIT(1);
|
lgcy_mmio_hole_en = tmp & BIT(1);
|
||||||
intlv_num_chan = (tmp >> 4) & 0xF;
|
intlv_num_chan = (tmp >> 4) & 0xF;
|
||||||
intlv_addr_sel = (tmp >> 8) & 0x7;
|
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))
|
if (amd_df_indirect_read(nid, 0, 0x114 + (8 * base), umc, &tmp))
|
||||||
goto out_err;
|
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;
|
intlv_num_dies = (tmp >> 10) & 0x3;
|
||||||
dram_limit_addr = ((tmp & GENMASK_ULL(31, 12)) << 16) | GENMASK_ULL(27, 0);
|
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) {
|
switch (intlv_num_chan) {
|
||||||
case 0: intlv_num_chan = 0; break;
|
case 0: intlv_num_chan = 0; break;
|
||||||
case 1: intlv_num_chan = 1; 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 3: intlv_num_chan = 2; break;
|
||||||
case 5: intlv_num_chan = 3; break;
|
case 5: intlv_num_chan = 3; break;
|
||||||
case 7: intlv_num_chan = 4; 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. */
|
/* Add a bit if sockets are interleaved. */
|
||||||
num_intlv_bits += intlv_num_sockets;
|
num_intlv_bits += intlv_num_sockets;
|
||||||
|
|
||||||
/* Assert num_intlv_bits <= 4 */
|
/* Assert num_intlv_bits in the correct range. */
|
||||||
if (num_intlv_bits > 4) {
|
if ((hygon_f18h_m4h() && num_intlv_bits > 7) ||
|
||||||
|
(!hygon_f18h_m4h() && num_intlv_bits > 4)) {
|
||||||
pr_err("%s: Invalid interleave bits %d.\n",
|
pr_err("%s: Invalid interleave bits %d.\n",
|
||||||
__func__, num_intlv_bits);
|
__func__, num_intlv_bits);
|
||||||
goto out_err;
|
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))
|
if (amd_df_indirect_read(nid, 0, 0x50, umc, &tmp))
|
||||||
goto out_err;
|
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;
|
die_id_bit = 0;
|
||||||
|
|
||||||
/* If interleaved over more than 1 channel: */
|
/* 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 interleaved over more than 1 die. */
|
||||||
if (intlv_num_dies) {
|
if (intlv_num_dies) {
|
||||||
sock_id_bit = die_id_bit + intlv_num_dies;
|
sock_id_bit = die_id_bit + intlv_num_dies;
|
||||||
die_id_shift = (tmp >> 24) & 0xF;
|
if (hygon_f18h_m4h()) {
|
||||||
die_id_mask = (tmp >> 8) & 0xFF;
|
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;
|
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 interleaved over more than 1 socket. */
|
||||||
if (intlv_num_sockets) {
|
if (intlv_num_sockets) {
|
||||||
socket_id_shift = (tmp >> 28) & 0xF;
|
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;
|
cs_id |= ((cs_fabric_id & socket_id_mask) >> socket_id_shift) << sock_id_bit;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue