Improve SDT checksum functions

This commit is contained in:
Lauri Kenttä
2016-05-14 17:23:05 +03:00
parent a633eeb781
commit 51ccb0255e
6 changed files with 72 additions and 21 deletions

View File

@@ -7,7 +7,7 @@ LIBS = -L$(GNUEFI_LIB) -lefi -lgcc
GNUEFI_INC = /usr/$(CC_PREFIX)/include/efi
GNUEFI_LIB = /usr/$(CC_PREFIX)/lib
FILES_C = src/main.c src/util.c src/config.c
FILES_C = src/main.c src/util.c src/types.c src/config.c
FILES_H = $(wildcard src/*.h)
.PHONY: all

View File

@@ -95,8 +95,7 @@ static void FillBGRT(ACPI_BGRT* bgrt, BMP* new_bmp, int new_x, int new_y) {
bgrt->image_offset_y = SelectCoordinate(new_y, y_auto, bgrt0.image_offset_y);
Debug(L"HackBGRT: BMP at (%d, %d).\n", (int) bgrt->image_offset_x, (int) bgrt->image_offset_y);
bgrt->header.checksum = 0;
bgrt->header.checksum = CalculateAcpiChecksum(bgrt, bgrt->header.length);
SetAcpiSdtChecksum(bgrt);
}
/**

37
src/types.c Normal file
View File

@@ -0,0 +1,37 @@
#include "types.h"
UINT8 SumBytes(const UINT8* arr, UINTN size) {
UINT8 sum = 0;
for (UINTN i = 0; i < size; ++i) {
sum += arr[i];
}
return sum;
}
int VerifyAcpiRsdp2Checksums(const void* data) {
const UINT8* arr = data;
UINTN size = *(const UINT32*)&arr[20];
return SumBytes(arr, 20) == 0 && SumBytes(arr, size) == 0;
}
void SetAcpiRsdp2Checksums(void* data) {
UINT8* arr = data;
UINTN size = *(const UINT32*)&arr[20];
arr[9] = 0;
arr[32] = 0;
arr[9] = -SumBytes(arr, 20);
arr[32] = -SumBytes(arr, size);
}
int VerifyAcpiSdtChecksum(const void* data) {
const UINT8* arr = data;
UINTN size = *(const UINT32*)&arr[4];
return SumBytes(arr, size) == 0;
}
void SetAcpiSdtChecksum(void* data) {
UINT8* arr = data;
UINTN size = *(const UINT32*)&arr[4];
arr[9] = 0;
arr[9] = -SumBytes(arr, size);
}

View File

@@ -1,5 +1,7 @@
#pragma once
#include <efi.h>
#pragma pack(push, 1)
/** RSDP (Root System Description Pointer) */
@@ -51,4 +53,35 @@ typedef struct {
UINT16 planes;
UINT16 bpp;
} BMP;
/**
* Verify the checksums of an ACPI RSDP version 2.
*
* @param data Pointer to the table.
* @return 1 if the checksum is correct, 0 otherwise.
*/
extern int VerifyAcpiRsdp2Checksums(const void* data);
/**
* Set the correct checksums of an ACPI RSDP version 2.
*
* @param data Pointer to the table.
*/
extern void SetAcpiRsdp2Checksums(void* data);
/**
* Verify the checksum of an ACPI SDT.
*
* @param data Pointer to the table.
* @return 1 if the checksum is correct, 0 otherwise.
*/
extern int VerifyAcpiSdtChecksum(const void* data);
/**
* Set the correct checksum for an ACPI SDT.
*
* @param data Pointer to the table.
*/
extern void SetAcpiSdtChecksum(void* data);
#pragma pack(pop)

View File

@@ -18,15 +18,6 @@ UINTN NullPrint(IN CHAR16 *fmt, ...) {
return 0;
}
UINT8 CalculateAcpiChecksum(void* data, UINTN size) {
UINT8 sum = 0;
UINT8* arr = data;
for (UINTN i = 0; i < size; ++i) {
sum += arr[i];
}
return 256 - sum;
}
const CHAR16* TrimLeft(const CHAR16* s) {
// Skip white-space and BOM.
while (s[0] == L'\xfeff' || s[0] == ' ' || s[0] == '\t') {

View File

@@ -16,15 +16,6 @@ extern const CHAR16* TmpStr(CHAR8 *src, int length);
*/
extern UINTN NullPrint(IN CHAR16 *fmt, ...);
/**
* Calculate the checksum for an ACPI table.
*
* @param data Pointer to the table.
* @param size Table length in bytes.
* @return Checksum.
*/
extern UINT8 CalculateAcpiChecksum(void* data, UINTN size);
/**
* Return the greater of two numbers.
*/