david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[acpi] Compute and check checksum for ACPI tables

Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Laurent Gourvénec 2017-07-27 16:04:35 +02:00 committed by Michael Brown
parent 8866c919f8
commit 041d362423
1 changed files with 37 additions and 6 deletions

View File

@ -42,19 +42,41 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
******************************************************************************
*/
/**
* Compute ACPI table checksum
*
* @v table Any ACPI table
* @ret checksum 0 if checksum is good
*/
static uint8_t acpi_checksum ( userptr_t table ) {
struct acpi_header acpi;
uint8_t sum = 0;
uint8_t data;
unsigned int i;
/* Read table length */
copy_from_user ( &acpi.length, table,
offsetof ( typeof ( acpi ), length ),
sizeof ( acpi.length ) );
/* Compute checksum */
for ( i = 0 ; i < le32_to_cpu ( acpi.length ) ; i++ ) {
copy_from_user ( &data, table, i, sizeof ( data ) );
sum += data;
}
return sum;
}
/**
* Fix up ACPI table checksum
*
* @v acpi ACPI table header
*/
void acpi_fix_checksum ( struct acpi_header *acpi ) {
unsigned int i = 0;
uint8_t sum = 0;
for ( i = 0 ; i < acpi->length ; i++ ) {
sum += *( ( ( uint8_t * ) acpi ) + i );
}
acpi->checksum -= sum;
/* Update checksum */
acpi->checksum -= acpi_checksum ( virt_to_user ( acpi ) );
}
/**
@ -123,6 +145,15 @@ userptr_t acpi_find ( uint32_t signature, unsigned int index ) {
if ( index-- )
continue;
/* Check table integrity */
if ( acpi_checksum ( table ) != 0 ) {
DBGC ( rsdt, "RSDT %#08lx found %s with bad checksum "
"at %08lx\n", user_to_phys ( rsdt, 0 ),
acpi_name ( signature ),
user_to_phys ( table, 0 ) );
break;
}
DBGC ( rsdt, "RSDT %#08lx found %s at %08lx\n",
user_to_phys ( rsdt, 0 ), acpi_name ( signature ),
user_to_phys ( table, 0 ) );