--- /dev/null
+#!/usr/bin/env python
+#
+# acpi_table_checksum - verify and calculate the checksum of ACPI tables
+#
+# Copyright (C) 2015 Antonio Ospite <ao2@ao2.it>
+#
+# This program is free software. It comes without any warranty, to
+# the extent permitted by applicable law. You can redistribute it
+# and/or modify it under the terms of the Do What The Fuck You Want
+# To Public License, Version 2, as published by Sam Hocevar. See
+# http://sam.zoy.org/wtfpl/COPYING for more details.
+
+import sys
+
+CHECKSUM_OFFSET = 9
+
+
+# Two's complement byte checksum:
+def acpi_table_checksum(buf, length):
+ checksum = 0
+
+ for i in range(0, length):
+ checksum = (checksum + buf[i]) & 0xff
+
+ return (0x100 - checksum) & 0xff
+
+
+def calc_new_checksum(data):
+ data_copy = data[:]
+ data_copy[CHECKSUM_OFFSET] = 0
+ return acpi_table_checksum(data_copy, len(data_copy))
+
+
+def verify_checksum(data):
+ return (acpi_table_checksum(data, len(data)) == 0)
+
+
+def usage():
+ print "%s <ACPI_TABLE>" % sys.argv[0]
+
+
+if __name__ == "__main__":
+ if len(sys.argv) != 2:
+ usage()
+ sys.exit(1)
+
+ table = sys.argv[1]
+
+ with open(table, 'rb') as f:
+ data = bytearray(f.read())
+
+ checksum_is_valid = verify_checksum(data)
+
+ if checksum_is_valid:
+ print "Checksum valid (0x%02x)." % data[CHECKSUM_OFFSET]
+ else:
+ print "Checksum not valid, calculating a new one..."
+ new_checksum = calc_new_checksum(data)
+ print "New checksum 0x%02x" % new_checksum
+ data[CHECKSUM_OFFSET] = new_checksum
+ print "Checksum vaiid %d" % verify_checksum(data)