0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "actables.h"
0013
0014 #define _COMPONENT ACPI_TABLES
0015 ACPI_MODULE_NAME("tbprint")
0016
0017
0018 static void acpi_tb_fix_string(char *string, acpi_size length);
0019
0020 static void
0021 acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
0022 struct acpi_table_header *header);
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 static void acpi_tb_fix_string(char *string, acpi_size length)
0039 {
0040
0041 while (length && *string) {
0042 if (!isprint((int)*string)) {
0043 *string = '?';
0044 }
0045
0046 string++;
0047 length--;
0048 }
0049 }
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 static void
0066 acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
0067 struct acpi_table_header *header)
0068 {
0069
0070 memcpy(out_header, header, sizeof(struct acpi_table_header));
0071
0072 acpi_tb_fix_string(out_header->signature, ACPI_NAMESEG_SIZE);
0073 acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE);
0074 acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
0075 acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAMESEG_SIZE);
0076 }
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 void
0092 acpi_tb_print_table_header(acpi_physical_address address,
0093 struct acpi_table_header *header)
0094 {
0095 struct acpi_table_header local_header;
0096
0097 if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_FACS)) {
0098
0099
0100
0101 ACPI_INFO(("%-4.4s 0x%8.8X%8.8X %06X",
0102 header->signature, ACPI_FORMAT_UINT64(address),
0103 header->length));
0104 } else if (ACPI_VALIDATE_RSDP_SIG(ACPI_CAST_PTR(struct acpi_table_rsdp,
0105 header)->signature)) {
0106
0107
0108
0109 memcpy(local_header.oem_id,
0110 ACPI_CAST_PTR(struct acpi_table_rsdp, header)->oem_id,
0111 ACPI_OEM_ID_SIZE);
0112 acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE);
0113
0114 ACPI_INFO(("RSDP 0x%8.8X%8.8X %06X (v%.2d %-6.6s)",
0115 ACPI_FORMAT_UINT64(address),
0116 (ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
0117 revision >
0118 0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
0119 header)->length : 20,
0120 ACPI_CAST_PTR(struct acpi_table_rsdp,
0121 header)->revision,
0122 local_header.oem_id));
0123 } else {
0124
0125
0126 acpi_tb_cleanup_table_header(&local_header, header);
0127
0128 ACPI_INFO(("%-4.4s 0x%8.8X%8.8X"
0129 " %06X (v%.2d %-6.6s %-8.8s %08X %-4.4s %08X)",
0130 local_header.signature, ACPI_FORMAT_UINT64(address),
0131 local_header.length, local_header.revision,
0132 local_header.oem_id, local_header.oem_table_id,
0133 local_header.oem_revision,
0134 local_header.asl_compiler_id,
0135 local_header.asl_compiler_revision));
0136 }
0137 }
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153 acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
0154 {
0155 u8 checksum;
0156
0157
0158
0159
0160
0161
0162 if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_S3PT) ||
0163 ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_FACS)) {
0164 return (AE_OK);
0165 }
0166
0167
0168
0169 checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length);
0170
0171
0172
0173 if (checksum) {
0174 ACPI_BIOS_WARNING((AE_INFO,
0175 "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
0176 "should be 0x%2.2X",
0177 table->signature, table->checksum,
0178 (u8)(table->checksum - checksum)));
0179
0180 #if (ACPI_CHECKSUM_ABORT)
0181 return (AE_BAD_CHECKSUM);
0182 #endif
0183 }
0184
0185 return (AE_OK);
0186 }
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201 u8 acpi_tb_checksum(u8 *buffer, u32 length)
0202 {
0203 u8 sum = 0;
0204 u8 *end = buffer + length;
0205
0206 while (buffer < end) {
0207 sum = (u8)(sum + *(buffer++));
0208 }
0209
0210 return (sum);
0211 }