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
|
#include "acpi.hpp"
#include "core/paging.hpp"
#include "drivers/framebuffer.hpp"
#include "libs/stdio.hpp"
#include "libs/string.hpp"
// TODO: ALL!
char acpi_load_madt(void* rsdp_p){
// Load RSDP
RSDP rsdp;
memcpy(rsdp_p, &rsdp, sizeof(rsdp));
if(rsdp.signature!=ACPI_RSDP_SIGNATURE){
printk("Invalid RSDP signature\n");
return 1;
}
if(acpi_checksum(rsdp_p, 20)){
printk("Wrong RSDP Signature\n\n");
return 1;
}
printk("ACPI Revision %d detected!\n",rsdp.revision);
// Load RSDT
RSDT rsdt;
paging_allocate_addr(kpml4,(u64)rsdp.rsdt_addr,(u64)rsdp.rsdt_addr,PAGING_OPT_P|PAGING_OPT_RW);
memcpy((void*)rsdp.rsdt_addr, &rsdt, sizeof(rsdt));
rsdt.first_entry_addr_ptr=rsdp.rsdt_addr+36;
if(rsdt.header.signature !=ACPI_RSDT_SIGNATURE){
printk("Invalid RSDT signature\n");
return 1;
}
if(acpi_checksum((void*)rsdp.rsdt_addr, rsdt.header.length)){
printk("Wrong RSDT Signature\n");
return 1;
}
// Locate MADT
for(int i=0;i<10;i++){
u32 *addr=(u32*)(rsdt.first_entry_addr_ptr+i*4);
u64 header_p_i=*addr;
ACPI_TABLE_HEADER header;
paging_allocate_addr(kpml4,header_p_i,header_p_i,PAGING_OPT_P|PAGING_OPT_RW);
memcpy((void*)header_p_i, &header, sizeof(header));
if(header.signature==ACPI_MADT_SIGNATURE){
printk("MADT found!");
}
}
return 0;
}
char acpi_checksum(void* p, char size){
char checksum=0;
char* data_p=(char*)p;
for(int i=0;i<size;i++){
checksum+=data_p[i];
}
return (checksum!=0);
}
|