aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2010-12-06 21:22:30 -0500
committerLen Brown <len.brown@intel.com>2010-12-13 23:42:12 -0500
commitf59c55d04b43bd72df8efa692dd07224fe94d1ac (patch)
tree31bcecf6a49230ae8735ba0f12ab4c30639c9094
parentc9aa308fd5c373faeda588cfb02b04f116904613 (diff)
ACPI, APEI, Add APEI generic error status printing support
In APEI, Hardware error information reported by firmware to Linux kernel is in the data structure of APEI generic error status (struct acpi_hes_generic_status). While now printk is used by Linux kernel to report hardware error information to user space. So, this patch adds printing support for the data structure, so that the corresponding hardware error information can be reported to user space via printk. PCIe AER information printing is not implemented yet. Will refactor the original PCIe AER information printing code to avoid code duplicating. The output format is as follow: <error record> := APEI generic hardware error status severity: <integer>, <severity string> section: <integer>, severity: <integer>, <severity string> flags: <integer> <section flags strings> fru_id: <uuid string> fru_text: <string> section_type: <section type string> <section data> <severity string>* := recoverable | fatal | corrected | info <section flags strings># := [primary][, containment warning][, reset][, threshold exceeded]\ [, resource not accessible][, latent error] <section type string> := generic processor error | memory error | \ PCIe error | unknown, <uuid string> <section data> := <generic processor section data> | <memory section data> | \ <pcie section data> | <null> <generic processor section data> := [processor_type: <integer>, <proc type string>] [processor_isa: <integer>, <proc isa string>] [error_type: <integer> <proc error type strings>] [operation: <integer>, <proc operation string>] [flags: <integer> <proc flags strings>] [level: <integer>] [version_info: <integer>] [processor_id: <integer>] [target_address: <integer>] [requestor_id: <integer>] [responder_id: <integer>] [IP: <integer>] <proc type string>* := IA32/X64 | IA64 <proc isa string>* := IA32 | IA64 | X64 <processor error type strings># := [cache error][, TLB error][, bus error][, micro-architectural error] <proc operation string>* := unknown or generic | data read | data write | \ instruction execution <proc flags strings># := [restartable][, precise IP][, overflow][, corrected] <memory section data> := [error_status: <integer>] [physical_address: <integer>] [physical_address_mask: <integer>] [node: <integer>] [card: <integer>] [module: <integer>] [bank: <integer>] [device: <integer>] [row: <integer>] [column: <integer>] [bit_position: <integer>] [requestor_id: <integer>] [responder_id: <integer>] [target_id: <integer>] [error_type: <integer>, <mem error type string>] <mem error type string>* := unknown | no error | single-bit ECC | multi-bit ECC | \ single-symbol chipkill ECC | multi-symbol chipkill ECC | master abort | \ target abort | parity error | watchdog timeout | invalid address | \ mirror Broken | memory sparing | scrub corrected error | \ scrub uncorrected error <pcie section data> := [port_type: <integer>, <pcie port type string>] [version: <integer>.<integer>] [command: <integer>, status: <integer>] [device_id: <integer>:<integer>:<integer>.<integer> slot: <integer> secondary_bus: <integer> vendor_id: <integer>, device_id: <integer> class_code: <integer>] [serial number: <integer>, <integer>] [bridge: secondary_status: <integer>, control: <integer>] <pcie port type string>* := PCIe end point | legacy PCI end point | \ unknown | unknown | root port | upstream switch port | \ downstream switch port | PCIe to PCI/PCI-X bridge | \ PCI/PCI-X to PCIe bridge | root complex integrated endpoint device | \ root complex event collector Where, [] designate corresponding content is optional All <field string> description with * has the following format: field: <integer>, <field string> Where value of <integer> should be the position of "string" in <field string> description. Otherwise, <field string> will be "unknown". All <field strings> description with # has the following format: field: <integer> <field strings> Where each string in <fields strings> corresponding to one set bit of <integer>. The bit position is the position of "string" in <field strings> description. For more detailed explanation of every field, please refer to UEFI specification version 2.3 or later, section Appendix N: Common Platform Error Record. Signed-off-by: Huang Ying <ying.huang@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--Documentation/acpi/apei/output_format.txt122
-rw-r--r--drivers/acpi/apei/apei-internal.h2
-rw-r--r--drivers/acpi/apei/cper.c311
3 files changed, 435 insertions, 0 deletions
diff --git a/Documentation/acpi/apei/output_format.txt b/Documentation/acpi/apei/output_format.txt
new file mode 100644
index 000000000000..9146952c612a
--- /dev/null
+++ b/Documentation/acpi/apei/output_format.txt
@@ -0,0 +1,122 @@
1 APEI output format
2 ~~~~~~~~~~~~~~~~~~
3
4APEI uses printk as hardware error reporting interface, the output
5format is as follow.
6
7<error record> :=
8APEI generic hardware error status
9severity: <integer>, <severity string>
10section: <integer>, severity: <integer>, <severity string>
11flags: <integer>
12<section flags strings>
13fru_id: <uuid string>
14fru_text: <string>
15section_type: <section type string>
16<section data>
17
18<severity string>* := recoverable | fatal | corrected | info
19
20<section flags strings># :=
21[primary][, containment warning][, reset][, threshold exceeded]\
22[, resource not accessible][, latent error]
23
24<section type string> := generic processor error | memory error | \
25PCIe error | unknown, <uuid string>
26
27<section data> :=
28<generic processor section data> | <memory section data> | \
29<pcie section data> | <null>
30
31<generic processor section data> :=
32[processor_type: <integer>, <proc type string>]
33[processor_isa: <integer>, <proc isa string>]
34[error_type: <integer>
35<proc error type strings>]
36[operation: <integer>, <proc operation string>]
37[flags: <integer>
38<proc flags strings>]
39[level: <integer>]
40[version_info: <integer>]
41[processor_id: <integer>]
42[target_address: <integer>]
43[requestor_id: <integer>]
44[responder_id: <integer>]
45[IP: <integer>]
46
47<proc type string>* := IA32/X64 | IA64
48
49<proc isa string>* := IA32 | IA64 | X64
50
51<processor error type strings># :=
52[cache error][, TLB error][, bus error][, micro-architectural error]
53
54<proc operation string>* := unknown or generic | data read | data write | \
55instruction execution
56
57<proc flags strings># :=
58[restartable][, precise IP][, overflow][, corrected]
59
60<memory section data> :=
61[error_status: <integer>]
62[physical_address: <integer>]
63[physical_address_mask: <integer>]
64[node: <integer>]
65[card: <integer>]
66[module: <integer>]
67[bank: <integer>]
68[device: <integer>]
69[row: <integer>]
70[column: <integer>]
71[bit_position: <integer>]
72[requestor_id: <integer>]
73[responder_id: <integer>]
74[target_id: <integer>]
75[error_type: <integer>, <mem error type string>]
76
77<mem error type string>* :=
78unknown | no error | single-bit ECC | multi-bit ECC | \
79single-symbol chipkill ECC | multi-symbol chipkill ECC | master abort | \
80target abort | parity error | watchdog timeout | invalid address | \
81mirror Broken | memory sparing | scrub corrected error | \
82scrub uncorrected error
83
84<pcie section data> :=
85[port_type: <integer>, <pcie port type string>]
86[version: <integer>.<integer>]
87[command: <integer>, status: <integer>]
88[device_id: <integer>:<integer>:<integer>.<integer>
89slot: <integer>
90secondary_bus: <integer>
91vendor_id: <integer>, device_id: <integer>
92class_code: <integer>]
93[serial number: <integer>, <integer>]
94[bridge: secondary_status: <integer>, control: <integer>]
95
96<pcie port type string>* := PCIe end point | legacy PCI end point | \
97unknown | unknown | root port | upstream switch port | \
98downstream switch port | PCIe to PCI/PCI-X bridge | \
99PCI/PCI-X to PCIe bridge | root complex integrated endpoint device | \
100root complex event collector
101
102Where, [] designate corresponding content is optional
103
104All <field string> description with * has the following format:
105
106field: <integer>, <field string>
107
108Where value of <integer> should be the position of "string" in <field
109string> description. Otherwise, <field string> will be "unknown".
110
111All <field strings> description with # has the following format:
112
113field: <integer>
114<field strings>
115
116Where each string in <fields strings> corresponding to one set bit of
117<integer>. The bit position is the position of "string" in <field
118strings> description.
119
120For more detailed explanation of every field, please refer to UEFI
121specification version 2.3 or later, section Appendix N: Common
122Platform Error Record.
diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h
index 18df1e940276..ef0581f2094d 100644
--- a/drivers/acpi/apei/apei-internal.h
+++ b/drivers/acpi/apei/apei-internal.h
@@ -109,6 +109,8 @@ static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus)
109 return sizeof(*estatus) + estatus->data_length; 109 return sizeof(*estatus) + estatus->data_length;
110} 110}
111 111
112void apei_estatus_print(const char *pfx,
113 const struct acpi_hest_generic_status *estatus);
112int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus); 114int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus);
113int apei_estatus_check(const struct acpi_hest_generic_status *estatus); 115int apei_estatus_check(const struct acpi_hest_generic_status *estatus);
114#endif 116#endif
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c
index f4cf2fc4c8c1..31464a006d76 100644
--- a/drivers/acpi/apei/cper.c
+++ b/drivers/acpi/apei/cper.c
@@ -46,6 +46,317 @@ u64 cper_next_record_id(void)
46} 46}
47EXPORT_SYMBOL_GPL(cper_next_record_id); 47EXPORT_SYMBOL_GPL(cper_next_record_id);
48 48
49static const char *cper_severity_strs[] = {
50 "recoverable",
51 "fatal",
52 "corrected",
53 "info",
54};
55
56static const char *cper_severity_str(unsigned int severity)
57{
58 return severity < ARRAY_SIZE(cper_severity_strs) ?
59 cper_severity_strs[severity] : "unknown";
60}
61
62/*
63 * cper_print_bits - print strings for set bits
64 * @pfx: prefix for each line, including log level and prefix string
65 * @bits: bit mask
66 * @strs: string array, indexed by bit position
67 * @strs_size: size of the string array: @strs
68 *
69 * For each set bit in @bits, print the corresponding string in @strs.
70 * If the output length is longer than 80, multiple line will be
71 * printed, with @pfx is printed at the beginning of each line.
72 */
73static void cper_print_bits(const char *pfx, unsigned int bits,
74 const char *strs[], unsigned int strs_size)