blob: af2bee407d0993b42f9ab0fd0ffae472d9dad739 [file] [log] [blame]
Felix Held2ecf1562021-07-14 00:30:53 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <amdblocks/mca.h>
4#include <amdblocks/msr_zen.h>
5#include <cpu/x86/msr.h>
6#include <acpi/acpi.h>
7#include <console/console.h>
8#include <arch/bert_storage.h>
9#include <cper.h>
10#include <types.h>
Felix Helda83a58f2021-07-14 00:51:40 +020011#include "mca_common_defs.h"
Felix Held2ecf1562021-07-14 00:30:53 +020012
13/* MISC4 is the last used register in the MCAX banks of Picasso */
14#define MCAX_USED_REGISTERS_PER_BANK (MCAX_MISC4_OFFSET + 1)
15
16static inline size_t mca_report_size_reqd(void)
17{
18 size_t size;
19
20 size = sizeof(acpi_generic_error_status_t);
21
22 size += sizeof(acpi_hest_generic_data_v300_t);
23 size += sizeof(cper_proc_generic_error_section_t);
24
25 size += sizeof(acpi_hest_generic_data_v300_t);
26 size += sizeof(cper_ia32x64_proc_error_section_t);
27
28 /* Check Error */
29 size += cper_ia32x64_check_sz();
30
31 /* Context of MCG_CAP, MCG_STAT, MCG_CTL */
32 size += cper_ia32x64_ctx_sz_bytype(CPER_IA32X64_CTX_MSR, 3);
33
34 /* Context of CTL, STATUS, ADDR, MISC0, CONFIG, IPID, SYND, RESERVED, DESTAT, DEADDR,
35 MISC1, MISC2, MISC3, MISC4 */
36 size += cper_ia32x64_ctx_sz_bytype(CPER_IA32X64_CTX_MSR, MCAX_USED_REGISTERS_PER_BANK);
37
38 /* Context of CTL_MASK */
39 size += cper_ia32x64_ctx_sz_bytype(CPER_IA32X64_CTX_MSR, 1);
40
41 return size;
42}
43
Felix Held2ecf1562021-07-14 00:30:53 +020044/* Convert an error reported by an MCA bank into BERT information to be reported
45 * by the OS. The ACPI driver doesn't recognize/parse the IA32/X64 structure,
46 * which is the best method to report MSR context. As a result, add two
47 * structures: A "processor generic error" that is parsed, and an IA32/X64 one
48 * to capture complete information.
49 */
50void build_bert_mca_error(struct mca_bank_status *mci)
51{
52 acpi_generic_error_status_t *status;
53 acpi_hest_generic_data_v300_t *gen_entry;
54 acpi_hest_generic_data_v300_t *x86_entry;
55 cper_proc_generic_error_section_t *gen_sec;
56 cper_ia32x64_proc_error_section_t *x86_sec;
57 cper_ia32x64_proc_error_info_t *chk;
58 cper_ia32x64_context_t *ctx;
59
60 if (mca_report_size_reqd() > bert_storage_remaining())
61 goto failed;
62
63 status = bert_new_event(&CPER_SEC_PROC_GENERIC_GUID);
64 if (!status)
65 goto failed;
66
67 gen_entry = acpi_hest_generic_data3(status);
68 gen_sec = section_of_acpientry(gen_sec, gen_entry);
69
70 fill_generic_section(gen_sec, mci);
71
72 x86_entry = bert_append_ia32x64(status);
73 x86_sec = section_of_acpientry(x86_sec, x86_entry);
74
75 chk = new_cper_ia32x64_check(status, x86_sec, error_to_chktype(mci));
76 if (!chk)
77 goto failed;
78
79 ctx = cper_new_ia32x64_context_msr(status, x86_sec, IA32_MCG_CAP, 3);
80 if (!ctx)
81 goto failed;
82 ctx = cper_new_ia32x64_context_msr(status, x86_sec, MCAX_CTL_MSR(mci->bank),
83 MCAX_USED_REGISTERS_PER_BANK);
84 if (!ctx)
85 goto failed;
86 ctx = cper_new_ia32x64_context_msr(status, x86_sec, MCA_CTL_MASK_MSR(mci->bank), 1);
87 if (!ctx)
88 goto failed;
89
90 return;
91
92failed:
93 /* We're here because of a hardware error, don't break something else */
Julius Wernere9665952022-01-21 17:06:20 -080094 printk(BIOS_ERR, "Not enough room in BERT region for Machine Check error\n");
Felix Held2ecf1562021-07-14 00:30:53 +020095}