xref: /aosp_15_r20/external/coreboot/src/soc/amd/common/block/cpu/mca/mca_common.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <amdblocks/mca.h>
4 #include <cpu/x86/msr.h>
5 #include <console/console.h>
6 #include <types.h>
7 #include "mca_common_defs.h"
8 
mca_check_all_banks(void)9 static void mca_check_all_banks(void)
10 {
11 	struct mca_bank_status mci;
12 	const unsigned int num_banks = mca_get_bank_count();
13 
14 	if (!mca_has_expected_bank_count())
15 		printk(BIOS_WARNING, "CPU has an unexpected number of MCA banks!\n");
16 
17 	if (mca_skip_check())
18 		return;
19 
20 	for (unsigned int i = 0 ; i < num_banks ; i++) {
21 		if (!mca_is_valid_bank(i))
22 			continue;
23 
24 		mci.bank = i;
25 		/* The MCA status register can be used in both the MCA and MCAX case */
26 		mci.sts = rdmsr(IA32_MC_STATUS(i));
27 		if (mci.sts.hi || mci.sts.lo) {
28 			mca_print_error(i);
29 
30 			if (CONFIG(ACPI_BERT) && mca_valid(mci.sts))
31 				build_bert_mca_error(&mci);
32 		}
33 	}
34 }
35 
check_mca(void)36 void check_mca(void)
37 {
38 	mca_check_all_banks();
39 	/* mca_clear_status uses the MCA registers which can be used in both the MCA and MCAX
40 	  case */
41 	mca_clear_status();
42 }
43