brintos

brintos / linux-shallow public Read only

0
0
Text · 4.6 KiB · b483894 Raw
171 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/******************************************************************************3 *4 * Module Name: utcksum - Support generating table checksums5 *6 * Copyright (C) 2000 - 2023, Intel Corp.7 *8 *****************************************************************************/9 10#include <acpi/acpi.h>11#include "accommon.h"12#include "acutils.h"13 14/* This module used for application-level code only */15 16#define _COMPONENT          ACPI_CA_DISASSEMBLER17ACPI_MODULE_NAME("utcksum")18 19/*******************************************************************************20 *21 * FUNCTION:    acpi_ut_verify_checksum22 *23 * PARAMETERS:  table               - ACPI table to verify24 *              length              - Length of entire table25 *26 * RETURN:      Status27 *28 * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns29 *              exception on bad checksum.30 *              Note: We don't have to check for a CDAT here, since CDAT is31 *              not in the RSDT/XSDT, and the CDAT table is never installed32 *              via ACPICA.33 *34 ******************************************************************************/35acpi_status acpi_ut_verify_checksum(struct acpi_table_header *table, u32 length)36{37	u8 checksum;38 39	/*40	 * FACS/S3PT:41	 * They are the odd tables, have no standard ACPI header and no checksum42	 */43	if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_S3PT) ||44	    ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_FACS)) {45		return (AE_OK);46	}47 48	/* Compute the checksum on the table */49 50	length = table->length;51	checksum =52	    acpi_ut_generate_checksum(ACPI_CAST_PTR(u8, table), length,53				      table->checksum);54 55	/* Computed checksum matches table? */56 57	if (checksum != table->checksum) {58		ACPI_BIOS_WARNING((AE_INFO,59				   "Incorrect checksum in table [%4.4s] - 0x%2.2X, "60				   "should be 0x%2.2X",61				   table->signature, table->checksum,62				   table->checksum - checksum));63 64#if (ACPI_CHECKSUM_ABORT)65		return (AE_BAD_CHECKSUM);66#endif67	}68 69	return (AE_OK);70}71 72/*******************************************************************************73 *74 * FUNCTION:    acpi_ut_verify_cdat_checksum75 *76 * PARAMETERS:  table               - CDAT ACPI table to verify77 *              length              - Length of entire table78 *79 * RETURN:      Status80 *81 * DESCRIPTION: Verifies that the CDAT table checksums to zero. Optionally82 *              returns an exception on bad checksum.83 *84 ******************************************************************************/85 86acpi_status87acpi_ut_verify_cdat_checksum(struct acpi_table_cdat *cdat_table, u32 length)88{89	u8 checksum;90 91	/* Compute the checksum on the table */92 93	checksum = acpi_ut_generate_checksum(ACPI_CAST_PTR(u8, cdat_table),94					     cdat_table->length,95					     cdat_table->checksum);96 97	/* Computed checksum matches table? */98 99	if (checksum != cdat_table->checksum) {100		ACPI_BIOS_WARNING((AE_INFO,101				   "Incorrect checksum in table [%4.4s] - 0x%2.2X, "102				   "should be 0x%2.2X",103				   acpi_gbl_CDAT, cdat_table->checksum,104				   checksum));105 106#if (ACPI_CHECKSUM_ABORT)107		return (AE_BAD_CHECKSUM);108#endif109	}110 111	cdat_table->checksum = checksum;112	return (AE_OK);113}114 115/*******************************************************************************116 *117 * FUNCTION:    acpi_ut_generate_checksum118 *119 * PARAMETERS:  table               - Pointer to table to be checksummed120 *              length              - Length of the table121 *              original_checksum   - Value of the checksum field122 *123 * RETURN:      8 bit checksum of buffer124 *125 * DESCRIPTION: Computes an 8 bit checksum of the table.126 *127 ******************************************************************************/128 129u8 acpi_ut_generate_checksum(void *table, u32 length, u8 original_checksum)130{131	u8 checksum;132 133	/* Sum the entire table as-is */134 135	checksum = acpi_ut_checksum((u8 *)table, length);136 137	/* Subtract off the existing checksum value in the table */138 139	checksum = (u8)(checksum - original_checksum);140 141	/* Compute and return the final checksum */142 143	checksum = (u8)(0 - checksum);144	return (checksum);145}146 147/*******************************************************************************148 *149 * FUNCTION:    acpi_ut_checksum150 *151 * PARAMETERS:  buffer          - Pointer to memory region to be checked152 *              length          - Length of this memory region153 *154 * RETURN:      Checksum (u8)155 *156 * DESCRIPTION: Calculates circular checksum of memory region.157 *158 ******************************************************************************/159 160u8 acpi_ut_checksum(u8 *buffer, u32 length)161{162	u8 sum = 0;163	u8 *end = buffer + length;164 165	while (buffer < end) {166		sum = (u8)(sum + *(buffer++));167	}168 169	return (sum);170}171