mirror of
https://github.com/torvalds/linux.git
synced 2026-06-05 04:56:13 +02:00
- Consider secondary address mask registers in amd64_edac in order to
get the correct total memory size of the system -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmhg+mIACgkQEsHwGGHe VUq4wQ//a8BsgU2zPe1pUP4EX6AsvNRbkmnlzOPwVPsKbKE9hRLJlI3AbwsbcF/a 1eU7LMaHgNRymO/AV5FpOEMJYKV1H+YnoBb4/Xam0dJoq82KAhSUXbATKsApbWo3 shO+t+jLA5w3eSOWbRSut1cfI+LWyotGPdpt6bfxYLFuA4zIAox8i75UPzj3MP0O dqJKOXTEmfZTxvJw/R6iJ9iFIl5QpmeqxlZKQtKwWuK+jkIDNk6jpB0o3qVGFdWj otzZq/d9LWeCvLLh/OuWSKVDG8ILvWSfro+pgiAYLPKCXeoT0J0mudPbYUhvVdK2 Gh95NKH4IbuZh1AUT27XwFMdrNZb1OlRQm4o2uJwCs9IFOoVcXUzAWw1wWqOfry1 tVpLsQtHmGOQSGEXbVZL8zbvnSi5k+7zx8V4xOHRIGkKapxNH3bXO4XvsMLPEDf5 gahGl/d0c+LVH7frIYD+ZGEEpRp7FALtyXt+wKtm/9B58L8LFwQXjZh3mKlDM/fd ciNcNa869dXM8J7D/qnuF0A6bFz2+oSYSAZYX+Zy/bHxkBEYeCwLBe6cCcaAOZF1 IC+WdyrxDmmIveFTAtu/X32NA6OLUYHW562mRVE3WMKLm5djYiLHAGEjHIJNcsmK Mfj3IMas6HX1MQFSwJ0Q5j2SVPpPSr8SwCi+YxLbmtyAV1Snyf8= =K5/s -----END PGP SIGNATURE----- Merge tag 'edac_urgent_for_v6.16_rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras Pull EDAC fix from Borislav Petkov: - Consider secondary address mask registers in amd64_edac in order to get the correct total memory size of the system * tag 'edac_urgent_for_v6.16_rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras: EDAC/amd64: Fix size calculation for Non-Power-of-Two DIMMs
This commit is contained in:
commit
3b1890e4b2
|
|
@ -1209,7 +1209,9 @@ static int umc_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt)
|
|||
if (csrow_enabled(2 * dimm + 1, ctrl, pvt))
|
||||
cs_mode |= CS_ODD_PRIMARY;
|
||||
|
||||
/* Asymmetric dual-rank DIMM support. */
|
||||
if (csrow_sec_enabled(2 * dimm, ctrl, pvt))
|
||||
cs_mode |= CS_EVEN_SECONDARY;
|
||||
|
||||
if (csrow_sec_enabled(2 * dimm + 1, ctrl, pvt))
|
||||
cs_mode |= CS_ODD_SECONDARY;
|
||||
|
||||
|
|
@ -1230,12 +1232,13 @@ static int umc_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt)
|
|||
return cs_mode;
|
||||
}
|
||||
|
||||
static int __addr_mask_to_cs_size(u32 addr_mask_orig, unsigned int cs_mode,
|
||||
int csrow_nr, int dimm)
|
||||
static int calculate_cs_size(u32 mask, unsigned int cs_mode)
|
||||
{
|
||||
u32 msb, weight, num_zero_bits;
|
||||
u32 addr_mask_deinterleaved;
|
||||
int size = 0;
|
||||
int msb, weight, num_zero_bits;
|
||||
u32 deinterleaved_mask;
|
||||
|
||||
if (!mask)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The number of zero bits in the mask is equal to the number of bits
|
||||
|
|
@ -1248,19 +1251,30 @@ static int __addr_mask_to_cs_size(u32 addr_mask_orig, unsigned int cs_mode,
|
|||
* without swapping with the most significant bit. This can be handled
|
||||
* by keeping the MSB where it is and ignoring the single zero bit.
|
||||
*/
|
||||
msb = fls(addr_mask_orig) - 1;
|
||||
weight = hweight_long(addr_mask_orig);
|
||||
msb = fls(mask) - 1;
|
||||
weight = hweight_long(mask);
|
||||
num_zero_bits = msb - weight - !!(cs_mode & CS_3R_INTERLEAVE);
|
||||
|
||||
/* Take the number of zero bits off from the top of the mask. */
|
||||
addr_mask_deinterleaved = GENMASK_ULL(msb - num_zero_bits, 1);
|
||||
deinterleaved_mask = GENMASK(msb - num_zero_bits, 1);
|
||||
edac_dbg(1, " Deinterleaved AddrMask: 0x%x\n", deinterleaved_mask);
|
||||
|
||||
return (deinterleaved_mask >> 2) + 1;
|
||||
}
|
||||
|
||||
static int __addr_mask_to_cs_size(u32 addr_mask, u32 addr_mask_sec,
|
||||
unsigned int cs_mode, int csrow_nr, int dimm)
|
||||
{
|
||||
int size;
|
||||
|
||||
edac_dbg(1, "CS%d DIMM%d AddrMasks:\n", csrow_nr, dimm);
|
||||
edac_dbg(1, " Original AddrMask: 0x%x\n", addr_mask_orig);
|
||||
edac_dbg(1, " Deinterleaved AddrMask: 0x%x\n", addr_mask_deinterleaved);
|
||||
edac_dbg(1, " Primary AddrMask: 0x%x\n", addr_mask);
|
||||
|
||||
/* Register [31:1] = Address [39:9]. Size is in kBs here. */
|
||||
size = (addr_mask_deinterleaved >> 2) + 1;
|
||||
size = calculate_cs_size(addr_mask, cs_mode);
|
||||
|
||||
edac_dbg(1, " Secondary AddrMask: 0x%x\n", addr_mask_sec);
|
||||
size += calculate_cs_size(addr_mask_sec, cs_mode);
|
||||
|
||||
/* Return size in MBs. */
|
||||
return size >> 10;
|
||||
|
|
@ -1269,8 +1283,8 @@ static int __addr_mask_to_cs_size(u32 addr_mask_orig, unsigned int cs_mode,
|
|||
static int umc_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc,
|
||||
unsigned int cs_mode, int csrow_nr)
|
||||
{
|
||||
u32 addr_mask = 0, addr_mask_sec = 0;
|
||||
int cs_mask_nr = csrow_nr;
|
||||
u32 addr_mask_orig;
|
||||
int dimm, size = 0;
|
||||
|
||||
/* No Chip Selects are enabled. */
|
||||
|
|
@ -1308,13 +1322,13 @@ static int umc_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc,
|
|||
if (!pvt->flags.zn_regs_v2)
|
||||
cs_mask_nr >>= 1;
|
||||
|
||||
/* Asymmetric dual-rank DIMM support. */
|
||||
if ((csrow_nr & 1) && (cs_mode & CS_ODD_SECONDARY))
|
||||
addr_mask_orig = pvt->csels[umc].csmasks_sec[cs_mask_nr];
|
||||
else
|
||||
addr_mask_orig = pvt->csels[umc].csmasks[cs_mask_nr];
|
||||
if (cs_mode & (CS_EVEN_PRIMARY | CS_ODD_PRIMARY))
|
||||
addr_mask = pvt->csels[umc].csmasks[cs_mask_nr];
|
||||
|
||||
return __addr_mask_to_cs_size(addr_mask_orig, cs_mode, csrow_nr, dimm);
|
||||
if (cs_mode & (CS_EVEN_SECONDARY | CS_ODD_SECONDARY))
|
||||
addr_mask_sec = pvt->csels[umc].csmasks_sec[cs_mask_nr];
|
||||
|
||||
return __addr_mask_to_cs_size(addr_mask, addr_mask_sec, cs_mode, csrow_nr, dimm);
|
||||
}
|
||||
|
||||
static void umc_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl)
|
||||
|
|
@ -3512,9 +3526,10 @@ static void gpu_get_err_info(struct mce *m, struct err_info *err)
|
|||
static int gpu_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc,
|
||||
unsigned int cs_mode, int csrow_nr)
|
||||
{
|
||||
u32 addr_mask_orig = pvt->csels[umc].csmasks[csrow_nr];
|
||||
u32 addr_mask = pvt->csels[umc].csmasks[csrow_nr];
|
||||
u32 addr_mask_sec = pvt->csels[umc].csmasks_sec[csrow_nr];
|
||||
|
||||
return __addr_mask_to_cs_size(addr_mask_orig, cs_mode, csrow_nr, csrow_nr >> 1);
|
||||
return __addr_mask_to_cs_size(addr_mask, addr_mask_sec, cs_mode, csrow_nr, csrow_nr >> 1);
|
||||
}
|
||||
|
||||
static void gpu_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user