2 #include "sys/apic_table.h"
4 #include "lib/string.h"
9 #define ACPI_PAGE_COUNT 32
11 uint32_t system_processors_found = 0;
14 size_t saddr = 0x000E0000;
15 char rsdp_ptr[8] = {
'R',
'S',
'D',
' ',
'P',
'T',
'R',
' '};
17 for(; saddr < 0x000FFFFF; saddr++) {
18 if(
memcmp((
const char*)saddr, (
const char*)rsdp_ptr, 8) == 0) {
19 qemu_log(
"Found! At: %x", saddr);
35 qemu_log(
"RSDP sig: %.8s", rsdp->signature);
36 qemu_log(
"RSDP checksum: %d", rsdp->checksum);
37 qemu_log(
"RSDP OEMID: %s", rsdp->OEMID);
38 qemu_log(
"RSDP revision: %d", rsdp->revision);
39 qemu_log(
"RSDT address: %x", rsdp->RSDTaddress);
41 if(rsdp->RSDTaddress == 0) {
49 unsigned char sum = 0;
51 for (
int i = 0; i < tableHeader->Length; i++) {
52 sum += ((
char*)tableHeader)[i];
58 ACPISDTHeader* find_table(uint32_t rsdt_addr, uint32_t sdt_count,
char signature[4]) {
59 uint32_t* rsdt_end = (uint32_t*)(rsdt_addr +
sizeof(
ACPISDTHeader));
61 map_pages_overlapping(
62 get_kernel_page_directory(),
65 PAGE_SIZE * ACPI_PAGE_COUNT,
69 qemu_log(
"RSDT start: %x", rsdt_addr);
70 qemu_log(
"RSDT end: %x", rsdt_end);
73 for(uint32_t i = 0; i < sdt_count; i++) {
76 if(
strncmp(entry->Signature, signature, 4) == 0) {
81 unmap_pages_overlapping(
82 get_kernel_page_directory(),
84 PAGE_SIZE * ACPI_PAGE_COUNT
90 void acpi_scan_all_tables(uint32_t rsdt_addr) {
93 map_pages_overlapping(
94 get_kernel_page_directory(),
97 PAGE_SIZE * ACPI_PAGE_COUNT,
101 uint32_t sdt_count = (rsdt->Length -
sizeof(
ACPISDTHeader)) /
sizeof(uint32_t);
103 qemu_log(
"LEN: %d (// %d)", rsdt->Length,
sizeof(
ACPISDTHeader));
105 uint32_t* rsdt_end = (uint32_t*)(rsdt_addr +
sizeof(
ACPISDTHeader));
107 qemu_log(
"RSDT start: %x", rsdt_addr);
108 qemu_log(
"RSDT end: %x", rsdt_end);
111 tty_printf(
"RSDT start: %x\n", rsdt_addr);
112 tty_printf(
"RSDT end: %x\n", rsdt_end);
113 tty_printf(
"SDT COUNT: %u\n", sdt_count);
115 for(uint32_t i = 0; i < sdt_count; i++) {
118 tty_printf(
"[%d/%d] [%x] Found table: %.4s\n", i, sdt_count, entry, entry->Signature);
119 qemu_log(
"[%x] Found table: %.4s", (
size_t)entry, entry->Signature);
122 unmap_pages_overlapping(
123 get_kernel_page_directory(),
125 PAGE_SIZE * ACPI_PAGE_COUNT
130 void find_facp(
size_t rsdt_addr) {
131 qemu_log(
"FACP at P%x", rsdt_addr);
133 map_pages_overlapping(
134 get_kernel_page_directory(),
147 bool check = acpi_checksum_sdt(rsdt);
149 qemu_log(
"Checksum: %s", check ?
"PASS" :
"FAIL");
152 qemu_log(
"INVALID RSDT TABLE!");
156 qemu_log(
"OEMID: %s", rsdt->OEMID);
157 qemu_log(
"Length: %d entries", rsdt->Length);
159 uint32_t sdt_count = (rsdt->Length -
sizeof(
ACPISDTHeader)) /
sizeof(uint32_t);
161 qemu_log(
"SDTs available: %d", sdt_count);
165 ACPISDTHeader* pre_fadt = find_table((uint32_t) rsdt_addr, sdt_count,
"FACP");
168 qemu_log(
"FADT not found...");
172 struct FADT* fadt = (
struct FADT*)(pre_fadt + 1);
176 qemu_log(
"Century: %d", fadt->Century);
177 qemu_log(
"SMI port: %x", fadt->SMI_CommandPort);
178 qemu_log(
"Enable Command: %x", fadt->AcpiEnable);
179 qemu_log(
"TODO: Write 'Enable Command' to 'SMI Port' using `outb()` func");
181 qemu_log(
"Found FADT!");
184 unmap_pages_overlapping(get_kernel_page_directory(), (virtual_addr_t) rsdt_addr, PAGE_SIZE * 2);
187 void find_apic(
size_t rsdt_addr,
size_t *lapic_addr) {
188 size_t start = rsdt_addr & ~0xfff;
189 size_t end = ALIGN(rsdt_addr + PAGE_SIZE, PAGE_SIZE);
192 get_kernel_page_directory(),
199 qemu_log(
"!!! Should be: %x - %x", start, end);
200 qemu_log(
"!!! Mapped memory range: %x - %x", rsdt_addr, rsdt_addr + (PAGE_SIZE));
203 bool check = acpi_checksum_sdt(rsdt);
205 qemu_log(
"Checksum: %s", check ?
"PASS" :
"FAIL");
208 qemu_log(
"INVALID RSDT TABLE!");
212 qemu_log(
"OEMID: %s", rsdt->OEMID);
213 qemu_log(
"Length: %d entries", rsdt->Length);
215 uint32_t sdt_count = (rsdt->Length -
sizeof(
ACPISDTHeader)) /
sizeof(uint32_t);
217 qemu_log(
"SDTs available: %d", sdt_count);
221 ACPISDTHeader* apic = find_table(rsdt_addr, sdt_count,
"APIC");
224 qemu_log(
"APIC not found...");
228 qemu_log(
"Found APIC!");
232 qemu_log(
"Table end at: %x", table_end);
236 qemu_log(
"LAPIC at: %x", apic_base->lapic_addr);
237 qemu_log(
"Flags: %x", apic_base->flags);
239 *lapic_addr = apic_base->lapic_addr;
243 for(
int i = 0; i < sdt_count; i++) {
246 qemu_log(
"[%x] Type: %d", entry, entry->type);
248 switch(entry->type) {
252 qemu_log(
"- Processor ID: %d", entry->entry.plapic.processor_id);
253 qemu_log(
"- Flags: %x", entry->entry.plapic.flags);
254 qemu_log(
"- APIC ID: %x", entry->entry.plapic.apic_id);
256 system_processors_found++;
264 qemu_log(
"- ID: %d", entry->entry.ioapic.id);
265 qemu_log(
"- IO APIC Address: %x", entry->entry.ioapic.io_apic_address);
266 qemu_log(
"- Global System Interrupt Base: %x", entry->entry.ioapic.global_system_interrupt_base);
272 qemu_log(
"IOAPIC Interrupt source override!");
274 qemu_log(
"- Bus Source: %d", entry->entry.ioapic_iso.bus_source);
275 qemu_log(
"- IRQ Source: %d", entry->entry.ioapic_iso.irq_source);
276 qemu_log(
"- Global System Interrupt: %x", entry->entry.ioapic_iso.global_system_interrupt);
277 qemu_log(
"- Flags: %x", entry->entry.ioapic_iso.flags);
283 qemu_log(
"IOAPIC NMI!");
285 qemu_log(
"- Source: %x", entry->entry.ioapic_nmi.source);
286 qemu_log(
"- Global System Interrupt: %x", entry->entry.ioapic_nmi.global_system_interrupt);
287 qemu_log(
"- Flags: %x", entry->entry.ioapic_nmi.flags);
293 qemu_log(
"LAPIC NMI!");
295 qemu_log(
"- Processor ID: %d", entry->entry.lapic_nmi.processor_id);
296 qemu_log(
"- LINT: %d", entry->entry.lapic_nmi.lint);
297 qemu_log(
"- Flags: %x", entry->entry.lapic_nmi.flags);
303 qemu_log(
"Unknown type! [%d]", entry->type);
305 goto apic_detect_end;
309 base_table_end += entry->record_length;
314 unmap_single_page(get_kernel_page_directory(), rsdt_addr);
int32_t strncmp(const char *s1, const char *s2, size_t num)
Сравнение строк с ограничением количества сравниваемых символов
int32_t memcmp(const char *s1, const char *s2, size_t n)
Сравнение массивов