| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
- /******************************************************************************
- *
- * Module Name: utcksum - Support generating table checksums
- *
- * Copyright (C) 2000 - 2025, Intel Corp.
- *
- *****************************************************************************/
- #include <acpi/acpi.h>
- #include "accommon.h"
- #include "acutils.h"
- /* This module used for application-level code only */
- #define _COMPONENT ACPI_CA_DISASSEMBLER
- ACPI_MODULE_NAME("utcksum")
- /*******************************************************************************
- *
- * FUNCTION: acpi_ut_verify_checksum
- *
- * PARAMETERS: table - ACPI table to verify
- * length - Length of entire table
- *
- * RETURN: Status
- *
- * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
- * exception on bad checksum.
- * Note: We don't have to check for a CDAT here, since CDAT is
- * not in the RSDT/XSDT, and the CDAT table is never installed
- * via ACPICA.
- *
- ******************************************************************************/
- acpi_status acpi_ut_verify_checksum(struct acpi_table_header *table, u32 length)
- {
- u8 checksum;
- /*
- * FACS/S3PT:
- * They are the odd tables, have no standard ACPI header and no checksum
- */
- if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_S3PT) ||
- ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_FACS)) {
- return (AE_OK);
- }
- /* Compute the checksum on the table */
- length = table->length;
- checksum =
- acpi_ut_generate_checksum(ACPI_CAST_PTR(u8, table), length,
- table->checksum);
- /* Computed checksum matches table? */
- if (checksum != table->checksum) {
- ACPI_BIOS_WARNING((AE_INFO,
- "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
- "should be 0x%2.2X",
- table->signature, table->checksum,
- table->checksum - checksum));
- #if (ACPI_CHECKSUM_ABORT)
- return (AE_BAD_CHECKSUM);
- #endif
- }
- return (AE_OK);
- }
- /*******************************************************************************
- *
- * FUNCTION: acpi_ut_verify_cdat_checksum
- *
- * PARAMETERS: table - CDAT ACPI table to verify
- * length - Length of entire table
- *
- * RETURN: Status
- *
- * DESCRIPTION: Verifies that the CDAT table checksums to zero. Optionally
- * returns an exception on bad checksum.
- *
- ******************************************************************************/
- acpi_status
- acpi_ut_verify_cdat_checksum(struct acpi_table_cdat *cdat_table, u32 length)
- {
- u8 checksum;
- /* Compute the checksum on the table */
- checksum = acpi_ut_generate_checksum(ACPI_CAST_PTR(u8, cdat_table),
- cdat_table->length,
- cdat_table->checksum);
- /* Computed checksum matches table? */
- if (checksum != cdat_table->checksum) {
- ACPI_BIOS_WARNING((AE_INFO,
- "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
- "should be 0x%2.2X",
- acpi_gbl_CDAT, cdat_table->checksum,
- checksum));
- #if (ACPI_CHECKSUM_ABORT)
- return (AE_BAD_CHECKSUM);
- #endif
- }
- cdat_table->checksum = checksum;
- return (AE_OK);
- }
- /*******************************************************************************
- *
- * FUNCTION: acpi_ut_generate_checksum
- *
- * PARAMETERS: table - Pointer to table to be checksummed
- * length - Length of the table
- * original_checksum - Value of the checksum field
- *
- * RETURN: 8 bit checksum of buffer
- *
- * DESCRIPTION: Computes an 8 bit checksum of the table.
- *
- ******************************************************************************/
- u8 acpi_ut_generate_checksum(void *table, u32 length, u8 original_checksum)
- {
- u8 checksum;
- /* Sum the entire table as-is */
- checksum = acpi_ut_checksum((u8 *)table, length);
- /* Subtract off the existing checksum value in the table */
- checksum = (u8)(checksum - original_checksum);
- /* Compute and return the final checksum */
- checksum = (u8)(0 - checksum);
- return (checksum);
- }
- /*******************************************************************************
- *
- * FUNCTION: acpi_ut_checksum
- *
- * PARAMETERS: buffer - Pointer to memory region to be checked
- * length - Length of this memory region
- *
- * RETURN: Checksum (u8)
- *
- * DESCRIPTION: Calculates circular checksum of memory region.
- *
- ******************************************************************************/
- u8 acpi_ut_checksum(u8 *buffer, u32 length)
- {
- u8 sum = 0;
- u8 *end = buffer + length;
- while (buffer < end) {
- sum = (u8)(sum + *(buffer++));
- }
- return (sum);
- }
|