blob: b4bb05e6e97078864a09bad38d2e19493bd835f7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
#include <acpi.h>
#include <vga.h>
#include <mem.h>
#include <stdbool.h>
static bool checksum_rsdp(const struct rsdp *rsdp) {
size_t chksm = 0;
for (uint8_t *byte = (uint8_t*) rsdp; byte < (uint8_t*)rsdp + sizeof(*rsdp); byte++)
chksm += *byte;
return (chksm & 0xFF) == 0;
}
static bool checksum_xsdp(const struct xsdp *rsdp) {
return true;
size_t chksm = 0;
for (uint8_t *byte = (uint8_t*) rsdp; byte < (uint8_t*)rsdp + sizeof(*rsdp); byte++)
chksm += *byte;
return (chksm & 0xFF) == 0;
}
static bool checksum_sdt(const struct acpi_sdt_header *header) {
uint8_t chksm = 0;
for (size_t i = 0; i < header->len; i++) {
chksm += ((int8_t *) header)[i];
}
return chksm == 0;
}
void print_rsdp(const struct rsdp *rsdp) {
vga_puts("sig: ");
vga_putsn(rsdp->signature, 8);
vga_putc('\n');
vga_puts("checksum: ");
vga_putn(rsdp->checksum);
vga_putc(' ');
vga_puts(checksum_rsdp(rsdp) ? "PASS" : "FAIL");
vga_putc('\n');
vga_puts("oem id: ");
vga_putsn(rsdp->oemid, 6);
vga_putc('\n');
vga_puts("revision: ");
vga_putn(rsdp->revision);
vga_putc('\n');
vga_puts("addr: ");
vga_putx(rsdp->rsdt_address);
vga_putc('\n');
}
struct fadt *find_facp(struct xsdt *root_sdt) {
if (root_sdt == NULL)
return NULL;
size_t entries = (root_sdt->header.len - sizeof(root_sdt->header)) / 4;
for (size_t i = 0; i < entries; i++) {
struct acpi_sdt_header *header = (struct acpi_sdt_header *) root_sdt->sdt_pointers[i];
if (memcmp(header->signature, "FACP", 4) == 0 && checksum_sdt(header)) {
return (struct fadt *) header;
}
}
return NULL;
}
struct xsdp *find_rsdp() {
struct xsdp *rsdp = NULL;
char *ebda = (char*)((uintptr_t) *(uint16_t *)0x40e << 4);
for (char *ptr = ebda; ptr < ebda + 128; ptr += 16) {
if (memcmp(ptr, "RSD PTR ", 8) == 0 && checksum_xsdp((struct xsdp*) ptr)) {
rsdp = (struct xsdp *) ptr;
}
}
for (char *ptr = (char*)0x000E0000; ptr < (char*)0x000FFFFF; ptr += 16) {
if (memcmp(ptr, "RSD PTR ", 8) == 0 && checksum_xsdp((struct xsdp*) ptr)) {
if (rsdp == NULL)
rsdp = (struct xsdp *) ptr;
}
}
//print_rsdp(rsdp);
return rsdp;
}
|