1 /****************************************************************************** 2 * 3 * Module Name: utcksum - Support generating table checksums 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2022, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "acpi.h" 45 #include "accommon.h" 46 #include "acdisasm.h" 47 #include "acutils.h" 48 49 50 /* This module used for application-level code only */ 51 52 #define _COMPONENT ACPI_CA_DISASSEMBLER 53 ACPI_MODULE_NAME ("utcksum") 54 55 56 /******************************************************************************* 57 * 58 * FUNCTION: AcpiUtVerifyChecksum 59 * 60 * PARAMETERS: Table - ACPI table to verify 61 * Length - Length of entire table 62 * 63 * RETURN: Status 64 * 65 * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns 66 * exception on bad checksum. 67 * Note: We don't have to check for a CDAT here, since CDAT is 68 * not in the RSDT/XSDT, and the CDAT table is never installed 69 * via ACPICA. 70 * 71 ******************************************************************************/ 72 73 ACPI_STATUS 74 AcpiUtVerifyChecksum ( 75 ACPI_TABLE_HEADER *Table, 76 UINT32 Length) 77 { 78 UINT8 Checksum; 79 80 81 /* 82 * FACS/S3PT: 83 * They are the odd tables, have no standard ACPI header and no checksum 84 */ 85 if (ACPI_COMPARE_NAMESEG (Table->Signature, ACPI_SIG_S3PT) || 86 ACPI_COMPARE_NAMESEG (Table->Signature, ACPI_SIG_FACS)) 87 { 88 return (AE_OK); 89 } 90 91 /* Compute the checksum on the table */ 92 93 Length = Table->Length; 94 Checksum = AcpiUtGenerateChecksum (ACPI_CAST_PTR (UINT8, Table), Length, Table->Checksum); 95 96 /* Computed checksum matches table? */ 97 98 if (Checksum != Table->Checksum) 99 { 100 ACPI_BIOS_WARNING ((AE_INFO, 101 "Incorrect checksum in table [%4.4s] - 0x%2.2X, " 102 "should be 0x%2.2X", 103 Table->Signature, Table->Checksum, 104 Table->Checksum - Checksum)); 105 106 #if (ACPI_CHECKSUM_ABORT) 107 return (AE_BAD_CHECKSUM); 108 #endif 109 } 110 111 return (AE_OK); 112 } 113 114 115 /******************************************************************************* 116 * 117 * FUNCTION: AcpiUtVerifyCdatChecksum 118 * 119 * PARAMETERS: Table - CDAT ACPI table to verify 120 * Length - Length of entire table 121 * 122 * RETURN: Status 123 * 124 * DESCRIPTION: Verifies that the CDAT table checksums to zero. Optionally 125 * returns an exception on bad checksum. 126 * 127 ******************************************************************************/ 128 129 ACPI_STATUS 130 AcpiUtVerifyCdatChecksum ( 131 ACPI_TABLE_CDAT *CdatTable, 132 UINT32 Length) 133 { 134 UINT8 Checksum; 135 136 137 /* Compute the checksum on the table */ 138 139 Checksum = AcpiUtGenerateChecksum (ACPI_CAST_PTR (UINT8, CdatTable), 140 CdatTable->Length, CdatTable->Checksum); 141 142 /* Computed checksum matches table? */ 143 144 if (Checksum != CdatTable->Checksum) 145 { 146 ACPI_BIOS_WARNING ((AE_INFO, 147 "Incorrect checksum in table [%4.4s] - 0x%2.2X, " 148 "should be 0x%2.2X", 149 AcpiGbl_CDAT, CdatTable->Checksum, Checksum)); 150 151 #if (ACPI_CHECKSUM_ABORT) 152 return (AE_BAD_CHECKSUM); 153 #endif 154 } 155 156 CdatTable->Checksum = Checksum; 157 return (AE_OK); 158 } 159 160 161 /******************************************************************************* 162 * 163 * FUNCTION: AcpiUtGenerateChecksum 164 * 165 * PARAMETERS: Table - Pointer to table to be checksummed 166 * Length - Length of the table 167 * OriginalChecksum - Value of the checksum field 168 * 169 * RETURN: 8 bit checksum of buffer 170 * 171 * DESCRIPTION: Computes an 8 bit checksum of the table. 172 * 173 ******************************************************************************/ 174 175 UINT8 176 AcpiUtGenerateChecksum ( 177 void *Table, 178 UINT32 Length, 179 UINT8 OriginalChecksum) 180 { 181 UINT8 Checksum; 182 183 184 /* Sum the entire table as-is */ 185 186 Checksum = AcpiUtChecksum ((UINT8 *) Table, Length); 187 188 /* Subtract off the existing checksum value in the table */ 189 190 Checksum = (UINT8) (Checksum - OriginalChecksum); 191 192 /* Compute and return the final checksum */ 193 194 Checksum = (UINT8) (0 - Checksum); 195 return (Checksum); 196 } 197 198 199 /******************************************************************************* 200 * 201 * FUNCTION: AcpiUtChecksum 202 * 203 * PARAMETERS: Buffer - Pointer to memory region to be checked 204 * Length - Length of this memory region 205 * 206 * RETURN: Checksum (UINT8) 207 * 208 * DESCRIPTION: Calculates circular checksum of memory region. 209 * 210 ******************************************************************************/ 211 212 UINT8 213 AcpiUtChecksum ( 214 UINT8 *Buffer, 215 UINT32 Length) 216 { 217 UINT8 Sum = 0; 218 UINT8 *End = Buffer + Length; 219 220 221 while (Buffer < End) 222 { 223 Sum = (UINT8) (Sum + *(Buffer++)); 224 } 225 226 return (Sum); 227 } 228