soc/amd/*/mca: factor out common MCA/MCAX check & print functionality
For Cezanne stubs are added for the functions that the SoC-specific code needs to provide. Since the mca_is_valid_bank stub on Cezanne always returns false, the checks get skipped for it at the moment. The actual functionality will be added in a later patch. Change-Id: Ic31e9b1ca7f8fac0721c95935c79150d7f774aa4 Signed-off-by: Felix Held <felix-coreboot@felixheld.de> Reviewed-on: https://review.coreboot.org/c/coreboot/+/56290 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
parent
64077de176
commit
e84c3f1898
|
@ -1,8 +1,19 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
#include <amdblocks/mca.h>
|
#include <amdblocks/mca.h>
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
void mca_check_all_banks(void)
|
bool mca_has_expected_bank_count(void)
|
||||||
{
|
{
|
||||||
/* TODO: Implement MCAX register checking and BERT table generation. */
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mca_is_valid_bank(unsigned int bank)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *mca_get_bank_name(unsigned int bank)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,5 +3,12 @@ ramstage-y += mca_common.c
|
||||||
ramstage-y += mca_common_bert.c
|
ramstage-y += mca_common_bert.c
|
||||||
endif # CONFIG_SOC_AMD_COMMON_BLOCK_MCA_COMMON
|
endif # CONFIG_SOC_AMD_COMMON_BLOCK_MCA_COMMON
|
||||||
|
|
||||||
ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_MCA) += mca_bert.c
|
ifeq ($(CONFIG_SOC_AMD_COMMON_BLOCK_MCA),y)
|
||||||
ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_MCAX) += mcax_bert.c
|
ramstage-y += mca_bert.c
|
||||||
|
ramstage-y += mca.c
|
||||||
|
endif # CONFIG_SOC_AMD_COMMON_BLOCK_MCA
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_SOC_AMD_COMMON_BLOCK_MCAX),y)
|
||||||
|
ramstage-y += mcax_bert.c
|
||||||
|
ramstage-y += mcax.c
|
||||||
|
endif # CONFIG_SOC_AMD_COMMON_BLOCK_MCAX
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#include <amdblocks/mca.h>
|
||||||
|
#include <amdblocks/reset.h>
|
||||||
|
#include <cpu/amd/msr.h>
|
||||||
|
#include <cpu/x86/lapic.h>
|
||||||
|
#include <cpu/x86/msr.h>
|
||||||
|
#include <console/console.h>
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
static void mca_print_error(unsigned int bank)
|
||||||
|
{
|
||||||
|
msr_t msr;
|
||||||
|
|
||||||
|
printk(BIOS_WARNING, "#MC Error: core %u, bank %u %s\n", initial_lapicid(), bank,
|
||||||
|
mca_get_bank_name(bank));
|
||||||
|
|
||||||
|
msr = rdmsr(IA32_MC_STATUS(bank));
|
||||||
|
printk(BIOS_WARNING, " MC%u_STATUS = %08x_%08x\n", bank, msr.hi, msr.lo);
|
||||||
|
msr = rdmsr(IA32_MC_ADDR(bank));
|
||||||
|
printk(BIOS_WARNING, " MC%u_ADDR = %08x_%08x\n", bank, msr.hi, msr.lo);
|
||||||
|
msr = rdmsr(IA32_MC_MISC(bank));
|
||||||
|
printk(BIOS_WARNING, " MC%u_MISC = %08x_%08x\n", bank, msr.hi, msr.lo);
|
||||||
|
msr = rdmsr(IA32_MC_CTL(bank));
|
||||||
|
printk(BIOS_WARNING, " MC%u_CTL = %08x_%08x\n", bank, msr.hi, msr.lo);
|
||||||
|
msr = rdmsr(MC_CTL_MASK(bank));
|
||||||
|
printk(BIOS_WARNING, " MC%u_CTL_MASK = %08x_%08x\n", bank, msr.hi, msr.lo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mca_check_all_banks(void)
|
||||||
|
{
|
||||||
|
struct mca_bank_status mci;
|
||||||
|
const unsigned int num_banks = mca_get_bank_count();
|
||||||
|
|
||||||
|
if (!is_warm_reset())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (unsigned int i = 0 ; i < num_banks ; i++) {
|
||||||
|
if (!mca_is_valid_bank(i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mci.bank = i;
|
||||||
|
mci.sts = rdmsr(IA32_MC_STATUS(i));
|
||||||
|
if (mci.sts.hi || mci.sts.lo) {
|
||||||
|
mca_print_error(i);
|
||||||
|
|
||||||
|
if (CONFIG(ACPI_BERT) && mca_valid(mci.sts))
|
||||||
|
build_bert_mca_error(&mci);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#include <amdblocks/mca.h>
|
||||||
|
#include <amdblocks/msr_zen.h>
|
||||||
|
#include <cpu/x86/lapic.h>
|
||||||
|
#include <cpu/x86/msr.h>
|
||||||
|
#include <console/console.h>
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
static void mca_print_error(unsigned int bank)
|
||||||
|
{
|
||||||
|
msr_t msr;
|
||||||
|
|
||||||
|
printk(BIOS_WARNING, "#MC Error: core %u, bank %u %s\n", initial_lapicid(), bank,
|
||||||
|
mca_get_bank_name(bank));
|
||||||
|
|
||||||
|
msr = rdmsr(MCAX_STATUS_MSR(bank));
|
||||||
|
printk(BIOS_WARNING, " MC%u_STATUS = %08x_%08x\n", bank, msr.hi, msr.lo);
|
||||||
|
msr = rdmsr(MCAX_ADDR_MSR(bank));
|
||||||
|
printk(BIOS_WARNING, " MC%u_ADDR = %08x_%08x\n", bank, msr.hi, msr.lo);
|
||||||
|
msr = rdmsr(MCAX_MISC0_MSR(bank));
|
||||||
|
printk(BIOS_WARNING, " MC%u_MISC = %08x_%08x\n", bank, msr.hi, msr.lo);
|
||||||
|
msr = rdmsr(MCAX_CTL_MSR(bank));
|
||||||
|
printk(BIOS_WARNING, " MC%u_CTL = %08x_%08x\n", bank, msr.hi, msr.lo);
|
||||||
|
msr = rdmsr(MCA_CTL_MASK_MSR(bank));
|
||||||
|
printk(BIOS_WARNING, " MC%u_CTL_MASK = %08x_%08x\n", bank, msr.hi, msr.lo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mca_check_all_banks(void)
|
||||||
|
{
|
||||||
|
struct mca_bank_status mci;
|
||||||
|
const unsigned int num_banks = mca_get_bank_count();
|
||||||
|
|
||||||
|
if (!mca_has_expected_bank_count())
|
||||||
|
printk(BIOS_WARNING, "CPU has an unexpected number of MCA banks!\n");
|
||||||
|
|
||||||
|
for (unsigned int i = 0 ; i < num_banks ; i++) {
|
||||||
|
if (!mca_is_valid_bank(i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mci.bank = i;
|
||||||
|
mci.sts = rdmsr(MCAX_STATUS_MSR(i));
|
||||||
|
if (mci.sts.hi || mci.sts.lo) {
|
||||||
|
mca_print_error(i);
|
||||||
|
|
||||||
|
if (CONFIG(ACPI_BERT) && mca_valid(mci.sts))
|
||||||
|
build_bert_mca_error(&mci);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
#define AMD_BLOCK_MCA_H
|
#define AMD_BLOCK_MCA_H
|
||||||
|
|
||||||
#include <cpu/x86/msr.h>
|
#include <cpu/x86/msr.h>
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
struct mca_bank_status {
|
struct mca_bank_status {
|
||||||
unsigned int bank;
|
unsigned int bank;
|
||||||
|
@ -13,5 +14,8 @@ struct mca_bank_status {
|
||||||
void check_mca(void);
|
void check_mca(void);
|
||||||
void mca_check_all_banks(void);
|
void mca_check_all_banks(void);
|
||||||
void build_bert_mca_error(struct mca_bank_status *mci);
|
void build_bert_mca_error(struct mca_bank_status *mci);
|
||||||
|
bool mca_has_expected_bank_count(void);
|
||||||
|
bool mca_is_valid_bank(unsigned int bank);
|
||||||
|
const char *mca_get_bank_name(unsigned int bank);
|
||||||
|
|
||||||
#endif /* AMD_BLOCK_MCA_H */
|
#endif /* AMD_BLOCK_MCA_H */
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
#include <amdblocks/mca.h>
|
#include <amdblocks/mca.h>
|
||||||
#include <amdblocks/msr_zen.h>
|
|
||||||
#include <cpu/x86/lapic.h>
|
|
||||||
#include <cpu/x86/msr.h>
|
#include <cpu/x86/msr.h>
|
||||||
#include <console/console.h>
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
static const char *const mca_bank_name[] = {
|
static const char *const mca_bank_name[] = {
|
||||||
|
@ -33,62 +30,20 @@ static const char *const mca_bank_name[] = {
|
||||||
[22] = "PIE",
|
[22] = "PIE",
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool mca_has_expected_bank_count(void)
|
bool mca_has_expected_bank_count(void)
|
||||||
{
|
{
|
||||||
return ARRAY_SIZE(mca_bank_name) == mca_get_bank_count();
|
return ARRAY_SIZE(mca_bank_name) == mca_get_bank_count();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mca_is_valid_bank(unsigned int bank)
|
bool mca_is_valid_bank(unsigned int bank)
|
||||||
{
|
{
|
||||||
return (bank < ARRAY_SIZE(mca_bank_name) && mca_bank_name[bank] != NULL);
|
return (bank < ARRAY_SIZE(mca_bank_name) && mca_bank_name[bank] != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *mca_get_bank_name(unsigned int bank)
|
const char *mca_get_bank_name(unsigned int bank)
|
||||||
{
|
{
|
||||||
if (mca_is_valid_bank(bank))
|
if (mca_is_valid_bank(bank))
|
||||||
return mca_bank_name[bank];
|
return mca_bank_name[bank];
|
||||||
else
|
else
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mca_print_error(unsigned int bank)
|
|
||||||
{
|
|
||||||
msr_t msr;
|
|
||||||
|
|
||||||
printk(BIOS_WARNING, "#MC Error: core %u, bank %u %s\n", initial_lapicid(), bank,
|
|
||||||
mca_get_bank_name(bank));
|
|
||||||
|
|
||||||
msr = rdmsr(MCAX_STATUS_MSR(bank));
|
|
||||||
printk(BIOS_WARNING, " MC%u_STATUS = %08x_%08x\n", bank, msr.hi, msr.lo);
|
|
||||||
msr = rdmsr(MCAX_ADDR_MSR(bank));
|
|
||||||
printk(BIOS_WARNING, " MC%u_ADDR = %08x_%08x\n", bank, msr.hi, msr.lo);
|
|
||||||
msr = rdmsr(MCAX_MISC0_MSR(bank));
|
|
||||||
printk(BIOS_WARNING, " MC%u_MISC = %08x_%08x\n", bank, msr.hi, msr.lo);
|
|
||||||
msr = rdmsr(MCAX_CTL_MSR(bank));
|
|
||||||
printk(BIOS_WARNING, " MC%u_CTL = %08x_%08x\n", bank, msr.hi, msr.lo);
|
|
||||||
msr = rdmsr(MCA_CTL_MASK_MSR(bank));
|
|
||||||
printk(BIOS_WARNING, " MC%u_CTL_MASK = %08x_%08x\n", bank, msr.hi, msr.lo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mca_check_all_banks(void)
|
|
||||||
{
|
|
||||||
struct mca_bank_status mci;
|
|
||||||
const unsigned int num_banks = mca_get_bank_count();
|
|
||||||
|
|
||||||
if (!mca_has_expected_bank_count())
|
|
||||||
printk(BIOS_WARNING, "CPU has an unexpected number of MCA banks!\n");
|
|
||||||
|
|
||||||
for (unsigned int i = 0 ; i < num_banks ; i++) {
|
|
||||||
if (!mca_is_valid_bank(i))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
mci.bank = i;
|
|
||||||
mci.sts = rdmsr(MCAX_STATUS_MSR(i));
|
|
||||||
if (mci.sts.hi || mci.sts.lo) {
|
|
||||||
mca_print_error(i);
|
|
||||||
|
|
||||||
if (CONFIG(ACPI_BERT) && mca_valid(mci.sts))
|
|
||||||
build_bert_mca_error(&mci);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
#include <amdblocks/mca.h>
|
#include <amdblocks/mca.h>
|
||||||
#include <amdblocks/reset.h>
|
|
||||||
#include <cpu/amd/msr.h>
|
|
||||||
#include <cpu/x86/lapic.h>
|
|
||||||
#include <cpu/x86/msr.h>
|
|
||||||
#include <console/console.h>
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
static const char *const mca_bank_name[] = {
|
static const char *const mca_bank_name[] = {
|
||||||
|
@ -20,57 +15,15 @@ static const char *const mca_bank_name[] = {
|
||||||
[6] = "Floating point unit"
|
[6] = "Floating point unit"
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool mca_is_valid_bank(unsigned int bank)
|
bool mca_is_valid_bank(unsigned int bank)
|
||||||
{
|
{
|
||||||
return (bank < ARRAY_SIZE(mca_bank_name) && mca_bank_name[bank] != NULL);
|
return (bank < ARRAY_SIZE(mca_bank_name) && mca_bank_name[bank] != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *mca_get_bank_name(unsigned int bank)
|
const char *mca_get_bank_name(unsigned int bank)
|
||||||
{
|
{
|
||||||
if (mca_is_valid_bank(bank))
|
if (mca_is_valid_bank(bank))
|
||||||
return mca_bank_name[bank];
|
return mca_bank_name[bank];
|
||||||
else
|
else
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mca_print_error(unsigned int bank)
|
|
||||||
{
|
|
||||||
msr_t msr;
|
|
||||||
|
|
||||||
printk(BIOS_WARNING, "#MC Error: core %u, bank %u %s\n", initial_lapicid(), bank,
|
|
||||||
mca_get_bank_name(bank));
|
|
||||||
|
|
||||||
msr = rdmsr(IA32_MC_STATUS(bank));
|
|
||||||
printk(BIOS_WARNING, " MC%u_STATUS = %08x_%08x\n", bank, msr.hi, msr.lo);
|
|
||||||
msr = rdmsr(IA32_MC_ADDR(bank));
|
|
||||||
printk(BIOS_WARNING, " MC%u_ADDR = %08x_%08x\n", bank, msr.hi, msr.lo);
|
|
||||||
msr = rdmsr(IA32_MC_MISC(bank));
|
|
||||||
printk(BIOS_WARNING, " MC%u_MISC = %08x_%08x\n", bank, msr.hi, msr.lo);
|
|
||||||
msr = rdmsr(IA32_MC_CTL(bank));
|
|
||||||
printk(BIOS_WARNING, " MC%u_CTL = %08x_%08x\n", bank, msr.hi, msr.lo);
|
|
||||||
msr = rdmsr(MC_CTL_MASK(bank));
|
|
||||||
printk(BIOS_WARNING, " MC%u_CTL_MASK = %08x_%08x\n", bank, msr.hi, msr.lo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mca_check_all_banks(void)
|
|
||||||
{
|
|
||||||
struct mca_bank_status mci;
|
|
||||||
const unsigned int num_banks = mca_get_bank_count();
|
|
||||||
|
|
||||||
if (!is_warm_reset())
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (unsigned int i = 0 ; i < num_banks ; i++) {
|
|
||||||
if (!mca_is_valid_bank(i))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
mci.bank = i;
|
|
||||||
mci.sts = rdmsr(IA32_MC_STATUS(i));
|
|
||||||
if (mci.sts.hi || mci.sts.lo) {
|
|
||||||
mca_print_error(i);
|
|
||||||
|
|
||||||
if (CONFIG(ACPI_BERT) && mca_valid(mci.sts))
|
|
||||||
build_bert_mca_error(&mci);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue