ACPI: sysfs: Fix BERT error region memory mapping
[linux-2.6-microblaze.git] / drivers / acpi / acpica / tbprint.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: tbprint - Table output utilities
5  *
6  * Copyright (C) 2000 - 2021, Intel Corp.
7  *
8  *****************************************************************************/
9
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12 #include "actables.h"
13
14 #define _COMPONENT          ACPI_TABLES
15 ACPI_MODULE_NAME("tbprint")
16
17 /* Local prototypes */
18 static void acpi_tb_fix_string(char *string, acpi_size length);
19
20 static void
21 acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
22                              struct acpi_table_header *header);
23
24 /*******************************************************************************
25  *
26  * FUNCTION:    acpi_tb_fix_string
27  *
28  * PARAMETERS:  string              - String to be repaired
29  *              length              - Maximum length
30  *
31  * RETURN:      None
32  *
33  * DESCRIPTION: Replace every non-printable or non-ascii byte in the string
34  *              with a question mark '?'.
35  *
36  ******************************************************************************/
37
38 static void acpi_tb_fix_string(char *string, acpi_size length)
39 {
40
41         while (length && *string) {
42                 if (!isprint((int)*string)) {
43                         *string = '?';
44                 }
45
46                 string++;
47                 length--;
48         }
49 }
50
51 /*******************************************************************************
52  *
53  * FUNCTION:    acpi_tb_cleanup_table_header
54  *
55  * PARAMETERS:  out_header          - Where the cleaned header is returned
56  *              header              - Input ACPI table header
57  *
58  * RETURN:      Returns the cleaned header in out_header
59  *
60  * DESCRIPTION: Copy the table header and ensure that all "string" fields in
61  *              the header consist of printable characters.
62  *
63  ******************************************************************************/
64
65 static void
66 acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
67                              struct acpi_table_header *header)
68 {
69
70         memcpy(out_header, header, sizeof(struct acpi_table_header));
71
72         acpi_tb_fix_string(out_header->signature, ACPI_NAMESEG_SIZE);
73         acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE);
74         acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
75         acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAMESEG_SIZE);
76 }
77
78 /*******************************************************************************
79  *
80  * FUNCTION:    acpi_tb_print_table_header
81  *
82  * PARAMETERS:  address             - Table physical address
83  *              header              - Table header
84  *
85  * RETURN:      None
86  *
87  * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP.
88  *
89  ******************************************************************************/
90
91 void
92 acpi_tb_print_table_header(acpi_physical_address address,
93                            struct acpi_table_header *header)
94 {
95         struct acpi_table_header local_header;
96
97         if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_FACS)) {
98
99                 /* FACS only has signature and length fields */
100
101                 ACPI_INFO(("%-4.4s 0x%8.8X%8.8X %06X",
102                            header->signature, ACPI_FORMAT_UINT64(address),
103                            header->length));
104         } else if (ACPI_VALIDATE_RSDP_SIG(ACPI_CAST_PTR(struct acpi_table_rsdp,
105                                                         header)->signature)) {
106
107                 /* RSDP has no common fields */
108
109                 memcpy(local_header.oem_id,
110                        ACPI_CAST_PTR(struct acpi_table_rsdp, header)->oem_id,
111                        ACPI_OEM_ID_SIZE);
112                 acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE);
113
114                 ACPI_INFO(("RSDP 0x%8.8X%8.8X %06X (v%.2d %-6.6s)",
115                            ACPI_FORMAT_UINT64(address),
116                            (ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
117                             revision >
118                             0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
119                                                header)->length : 20,
120                            ACPI_CAST_PTR(struct acpi_table_rsdp,
121                                          header)->revision,
122                            local_header.oem_id));
123         } else {
124                 /* Standard ACPI table with full common header */
125
126                 acpi_tb_cleanup_table_header(&local_header, header);
127
128                 ACPI_INFO(("%-4.4s 0x%8.8X%8.8X"
129                            " %06X (v%.2d %-6.6s %-8.8s %08X %-4.4s %08X)",
130                            local_header.signature, ACPI_FORMAT_UINT64(address),
131                            local_header.length, local_header.revision,
132                            local_header.oem_id, local_header.oem_table_id,
133                            local_header.oem_revision,
134                            local_header.asl_compiler_id,
135                            local_header.asl_compiler_revision));
136         }
137 }
138
139 /*******************************************************************************
140  *
141  * FUNCTION:    acpi_tb_validate_checksum
142  *
143  * PARAMETERS:  table               - ACPI table to verify
144  *              length              - Length of entire table
145  *
146  * RETURN:      Status
147  *
148  * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
149  *              exception on bad checksum.
150  *
151  ******************************************************************************/
152
153 acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
154 {
155         u8 checksum;
156
157         /*
158          * FACS/S3PT:
159          * They are the odd tables, have no standard ACPI header and no checksum
160          */
161
162         if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_S3PT) ||
163             ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_FACS)) {
164                 return (AE_OK);
165         }
166
167         /* Compute the checksum on the table */
168
169         checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length);
170
171         /* Checksum ok? (should be zero) */
172
173         if (checksum) {
174                 ACPI_BIOS_WARNING((AE_INFO,
175                                    "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
176                                    "should be 0x%2.2X",
177                                    table->signature, table->checksum,
178                                    (u8)(table->checksum - checksum)));
179
180 #if (ACPI_CHECKSUM_ABORT)
181                 return (AE_BAD_CHECKSUM);
182 #endif
183         }
184
185         return (AE_OK);
186 }
187
188 /*******************************************************************************
189  *
190  * FUNCTION:    acpi_tb_checksum
191  *
192  * PARAMETERS:  buffer          - Pointer to memory region to be checked
193  *              length          - Length of this memory region
194  *
195  * RETURN:      Checksum (u8)
196  *
197  * DESCRIPTION: Calculates circular checksum of memory region.
198  *
199  ******************************************************************************/
200
201 u8 acpi_tb_checksum(u8 *buffer, u32 length)
202 {
203         u8 sum = 0;
204         u8 *end = buffer + length;
205
206         while (buffer < end) {
207                 sum = (u8)(sum + *(buffer++));
208         }
209
210         return (sum);
211 }