mirror of https://github.com/ipxe/ipxe.git
[acpi] Compute and check checksum for ACPI tables
Modified-by: Michael Brown <mcb30@ipxe.org> Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/66/head
parent
8866c919f8
commit
041d362423
|
@ -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
|
* Fix up ACPI table checksum
|
||||||
*
|
*
|
||||||
* @v acpi ACPI table header
|
* @v acpi ACPI table header
|
||||||
*/
|
*/
|
||||||
void acpi_fix_checksum ( struct acpi_header *acpi ) {
|
void acpi_fix_checksum ( struct acpi_header *acpi ) {
|
||||||
unsigned int i = 0;
|
|
||||||
uint8_t sum = 0;
|
|
||||||
|
|
||||||
for ( i = 0 ; i < acpi->length ; i++ ) {
|
/* Update checksum */
|
||||||
sum += *( ( ( uint8_t * ) acpi ) + i );
|
acpi->checksum -= acpi_checksum ( virt_to_user ( acpi ) );
|
||||||
}
|
|
||||||
acpi->checksum -= sum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,6 +145,15 @@ userptr_t acpi_find ( uint32_t signature, unsigned int index ) {
|
||||||
if ( index-- )
|
if ( index-- )
|
||||||
continue;
|
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",
|
DBGC ( rsdt, "RSDT %#08lx found %s at %08lx\n",
|
||||||
user_to_phys ( rsdt, 0 ), acpi_name ( signature ),
|
user_to_phys ( rsdt, 0 ), acpi_name ( signature ),
|
||||||
user_to_phys ( table, 0 ) );
|
user_to_phys ( table, 0 ) );
|
||||||
|
|
Loading…
Reference in New Issue