LF OS
Hobby operating system for amd64 with high ambitions
Loading...
Searching...
No Matches
acpi.c
Go to the documentation of this file.
1#include <log.h>
2#include <acpi.h>
3#include <hpet.h>
4#include <string.h>
5#include <vm.h>
7struct acpi_rsdp {
8 char signature[8];
10 char oem_id[6];
17}__attribute__((packed));
18
23
28
29static void acpi_process_table(struct acpi_table_header* table) {
30 char signature[5];
31 memcpy(signature, table->signature, 4);
32 signature[4] = 0;
33
34 char oem[7];
35 memcpy(oem, table->oem_id, 6);
36 oem[6] = 0;
37
38 char oem_table[9];
39 memcpy(oem_table, table->oem_table_id, 8);
40 oem_table[8] = 0;
41
42 char creator[5];
43 memcpy(creator, table->asl_compiler_id, 4);
44 creator[4] = 0;
45
46 uint64_t length = table->length;
47 uint64_t revision = table->revision;
49 uint64_t creator_revision = table->asl_compiler_revision;
50
51 bool checksum_valid = acpi_checksum(table, table->length) == 0;
52
53 logd("acpi", "signature: \"%s\", length: %d, revision: %d, checksum: %s, oem: \"%s\"/\"%s\" (%d), creator: \"%s\" (%d)",
55 checksum_valid ? "ok" : "not ok",
56 oem, oem_table, oem_revision,
57 creator, creator_revision
58 );
59
60 if(!checksum_valid) {
61 loge("acpi", "checksum for table %s invalid, aborting", signature);
62 return;
63 }
64
65 if(memcmp(table->signature, "HPET", 4) == 0) {
66 init_hpet(table);
67 }
68}
69
70static void init_acpi_rsdp(void* rsdp_ptr) {
71 struct acpi_rsdp* rsdp = (struct acpi_rsdp*)rsdp_ptr;
72
73 char signature[9];
74 memcpy(signature, rsdp->signature, 8);
75 signature[8] = 0;
76
77 char oem[7];
78 memcpy(oem, rsdp->oem_id, 6);
79 oem[6] = 0;
80
81 uint64_t length = rsdp->length;
83 uint64_t rsdt = rsdp->rsdt_ptr;
84
85 bool checksum_valid = acpi_checksum(rsdp, 20) == 0;
86 bool xchecksum_valid = acpi_checksum(rsdp, rsdp->length) == 0;
87
88 logd("acpi", "signature: \"%s\", oem: \"%s\", length: %d, revision: %d, checksum: %s/%s, rsdt: %x, xsdt: %x",
90 checksum_valid ? "ok" : "not ok",
91 xchecksum_valid ? "ok" : "not ok",
92 rsdt, rsdp->xsdt_ptr
93 );
94
95 if(!checksum_valid) {
96 loge("acpi", "RSDP table checksum invalid, aborting");
97 return;
98 }
99
100 if(rsdp->revision >= 2 && !xchecksum_valid) {
101 loge("acpi", "RSDP table revision 2 but extended checksum invalid, aborting");
102 return;
103 }
104
105 if(rsdp->revision >= 2) {
106 struct acpi_xsdt* xsdt = (struct acpi_xsdt*)(rsdp->xsdt_ptr + ALLOCATOR_REGION_DIRECT_MAPPING.start);
107 if(acpi_checksum(xsdt, xsdt->header.length) != 0) {
108 loge("acpi", "XSDT table checksum invalid, aborting");
109 return;
110 }
111
112 size_t num_entries = (xsdt->header.length - sizeof(xsdt->header)) / sizeof(uint64_t);
113 logd("acpi", "%d entries in XSDT", num_entries);
114
115 for(size_t i = 0; i < num_entries; ++i) {
117 }
118 } else {
119 struct acpi_rsdt* rsdt = (struct acpi_rsdt*)(rsdp->rsdt_ptr + ALLOCATOR_REGION_DIRECT_MAPPING.start);
120 if(acpi_checksum(rsdt, rsdt->header.length) != 0) {
121 loge("acpi", "RSDT table checksum invalid, aborting");
122 return;
123 }
124
125 size_t num_entries = (rsdt->header.length - sizeof(rsdt->header)) / sizeof(uint32_t);
126 logd("acpi", "%d entries in RSDT", num_entries);
127
128 for(size_t i = 0; i < num_entries; ++i) {
130 }
131 }
132}
133
134static EFI_GUID efi_acpi_table_guid = EFI_ACPI_TABLE_GUID;
135
136void init_acpi_efi(EFI_SYSTEM_TABLE* efiST) {
137 for(size_t i = 0; i < efiST->NumberOfTableEntries; ++i) {
138 EFI_CONFIGURATION_TABLE* ct = &efiST->ConfigurationTable[i];
139
140 if(memcmp(&ct->VendorGuid, &efi_acpi_table_guid, sizeof(EFI_GUID)) == 0) {
141 logi("acpi", "EFI configuration table %d is an ACPI table");
142 init_acpi_rsdp((char*)ct->VendorTable + ALLOCATOR_REGION_DIRECT_MAPPING.start);
143 }
144 }
145}
146
147uint8_t acpi_checksum(void* data, size_t len) {
148 uint8_t ret = 0;
149 for(size_t i = 0; i < len; ++i) {
150 ret += ((char*)data)[i];
151 }
152
153 return ret;
154}
static void acpi_process_table(struct acpi_table_header *table)
Definition acpi.c:29
char signature[8]
Definition acpi.c:8
static void init_acpi_rsdp(void *rsdp_ptr)
Definition acpi.c:70
uint64_t xsdt_ptr
Definition acpi.c:14
static EFI_GUID efi_acpi_table_guid
Definition acpi.c:134
struct acpi_table_header header
Definition acpi.c:25
uint8_t checksum
Definition acpi.c:9
char signature[8]
Definition acpi.c:0
uint32_t rsdt_ptr
Definition acpi.c:12
uint32_t entry_ptr[0]
Definition acpi.c:21
uint32_t length
Definition acpi.c:13
char oem_id[6]
Definition acpi.c:10
uint8_t _reserved[3]
Definition acpi.c:16
uint8_t revision
Definition acpi.c:11
uint8_t revision
Definition acpi.c:3
void init_acpi_efi(EFI_SYSTEM_TABLE *efiST)
Definition acpi.c:136
uint64_t entry_ptr[0]
Definition acpi.c:26
uint8_t extended_checksum
Definition acpi.c:15
uint32_t length
Definition acpi.c:5
uint8_t acpi_checksum(void *data, size_t len)
Definition acpi.c:147
struct acpi_table_header header
Definition acpi.c:20
char signature[4]
Definition acpi.h:8
uint8_t revision
Definition acpi.h:10
char oem_id[6]
Definition acpi.h:12
uint32_t oem_revision
Definition acpi.h:14
uint32_t oem_revision
Definition acpi.h:6
char asl_compiler_id[4]
Definition acpi.h:15
uint32_t asl_compiler_revision
Definition acpi.h:16
char oem_table_id[8]
Definition acpi.h:13
uint32_t length
Definition acpi.h:9
unsigned int uint32_t
Definition arch.h:11
unsigned long uint64_t
Definition arch.h:14
unsigned char uint8_t
Definition arch.h:5
void init_hpet(struct acpi_table_header *header)
Definition hpet.c:104
uint8_t oem
Definition hpet.c:14
#define ALLOCATOR_REGION_DIRECT_MAPPING
Definition vm.h:29
void * memcpy(void *dest, void const *source, size_t size)
Definition string.c:80
int memcmp(const void *s1, const void *s2, size_t size)
Definition string.c:91
#define logd(component, fmt,...)
Definition log.h:28
#define logi(component, fmt,...)
Definition log.h:36
#define loge(component, fmt,...)
Definition log.h:52