utcksum.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /******************************************************************************
  3. *
  4. * Module Name: utcksum - Support generating table checksums
  5. *
  6. * Copyright (C) 2000 - 2025, Intel Corp.
  7. *
  8. *****************************************************************************/
  9. #include <acpi/acpi.h>
  10. #include "accommon.h"
  11. #include "acutils.h"
  12. /* This module used for application-level code only */
  13. #define _COMPONENT ACPI_CA_DISASSEMBLER
  14. ACPI_MODULE_NAME("utcksum")
  15. /*******************************************************************************
  16. *
  17. * FUNCTION: acpi_ut_verify_checksum
  18. *
  19. * PARAMETERS: table - ACPI table to verify
  20. * length - Length of entire table
  21. *
  22. * RETURN: Status
  23. *
  24. * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
  25. * exception on bad checksum.
  26. * Note: We don't have to check for a CDAT here, since CDAT is
  27. * not in the RSDT/XSDT, and the CDAT table is never installed
  28. * via ACPICA.
  29. *
  30. ******************************************************************************/
  31. acpi_status acpi_ut_verify_checksum(struct acpi_table_header *table, u32 length)
  32. {
  33. u8 checksum;
  34. /*
  35. * FACS/S3PT:
  36. * They are the odd tables, have no standard ACPI header and no checksum
  37. */
  38. if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_S3PT) ||
  39. ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_FACS)) {
  40. return (AE_OK);
  41. }
  42. /* Compute the checksum on the table */
  43. length = table->length;
  44. checksum =
  45. acpi_ut_generate_checksum(ACPI_CAST_PTR(u8, table), length,
  46. table->checksum);
  47. /* Computed checksum matches table? */
  48. if (checksum != table->checksum) {
  49. ACPI_BIOS_WARNING((AE_INFO,
  50. "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
  51. "should be 0x%2.2X",
  52. table->signature, table->checksum,
  53. table->checksum - checksum));
  54. #if (ACPI_CHECKSUM_ABORT)
  55. return (AE_BAD_CHECKSUM);
  56. #endif
  57. }
  58. return (AE_OK);
  59. }
  60. /*******************************************************************************
  61. *
  62. * FUNCTION: acpi_ut_verify_cdat_checksum
  63. *
  64. * PARAMETERS: table - CDAT ACPI table to verify
  65. * length - Length of entire table
  66. *
  67. * RETURN: Status
  68. *
  69. * DESCRIPTION: Verifies that the CDAT table checksums to zero. Optionally
  70. * returns an exception on bad checksum.
  71. *
  72. ******************************************************************************/
  73. acpi_status
  74. acpi_ut_verify_cdat_checksum(struct acpi_table_cdat *cdat_table, u32 length)
  75. {
  76. u8 checksum;
  77. /* Compute the checksum on the table */
  78. checksum = acpi_ut_generate_checksum(ACPI_CAST_PTR(u8, cdat_table),
  79. cdat_table->length,
  80. cdat_table->checksum);
  81. /* Computed checksum matches table? */
  82. if (checksum != cdat_table->checksum) {
  83. ACPI_BIOS_WARNING((AE_INFO,
  84. "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
  85. "should be 0x%2.2X",
  86. acpi_gbl_CDAT, cdat_table->checksum,
  87. checksum));
  88. #if (ACPI_CHECKSUM_ABORT)
  89. return (AE_BAD_CHECKSUM);
  90. #endif
  91. }
  92. cdat_table->checksum = checksum;
  93. return (AE_OK);
  94. }
  95. /*******************************************************************************
  96. *
  97. * FUNCTION: acpi_ut_generate_checksum
  98. *
  99. * PARAMETERS: table - Pointer to table to be checksummed
  100. * length - Length of the table
  101. * original_checksum - Value of the checksum field
  102. *
  103. * RETURN: 8 bit checksum of buffer
  104. *
  105. * DESCRIPTION: Computes an 8 bit checksum of the table.
  106. *
  107. ******************************************************************************/
  108. u8 acpi_ut_generate_checksum(void *table, u32 length, u8 original_checksum)
  109. {
  110. u8 checksum;
  111. /* Sum the entire table as-is */
  112. checksum = acpi_ut_checksum((u8 *)table, length);
  113. /* Subtract off the existing checksum value in the table */
  114. checksum = (u8)(checksum - original_checksum);
  115. /* Compute and return the final checksum */
  116. checksum = (u8)(0 - checksum);
  117. return (checksum);
  118. }
  119. /*******************************************************************************
  120. *
  121. * FUNCTION: acpi_ut_checksum
  122. *
  123. * PARAMETERS: buffer - Pointer to memory region to be checked
  124. * length - Length of this memory region
  125. *
  126. * RETURN: Checksum (u8)
  127. *
  128. * DESCRIPTION: Calculates circular checksum of memory region.
  129. *
  130. ******************************************************************************/
  131. u8 acpi_ut_checksum(u8 *buffer, u32 length)
  132. {
  133. u8 sum = 0;
  134. u8 *end = buffer + length;
  135. while (buffer < end) {
  136. sum = (u8)(sum + *(buffer++));
  137. }
  138. return (sum);
  139. }