xref: /kvm-unit-tests/lib/acpi.c (revision 372e3528a7881eea82805fa7f3e206be9db6ed7e)
1372e3528SPaolo Bonzini #include "libcflat.h"
2372e3528SPaolo Bonzini #include "acpi.h"
3372e3528SPaolo Bonzini 
4372e3528SPaolo Bonzini void* find_acpi_table_addr(u32 sig)
5372e3528SPaolo Bonzini {
6372e3528SPaolo Bonzini     unsigned long addr;
7372e3528SPaolo Bonzini     struct rsdp_descriptor *rsdp;
8372e3528SPaolo Bonzini     struct rsdt_descriptor_rev1 *rsdt;
9372e3528SPaolo Bonzini     void *end;
10372e3528SPaolo Bonzini     int i;
11372e3528SPaolo Bonzini 
12372e3528SPaolo Bonzini     /* FACS is special... */
13372e3528SPaolo Bonzini     if (sig == FACS_SIGNATURE) {
14372e3528SPaolo Bonzini         struct fadt_descriptor_rev1 *fadt;
15372e3528SPaolo Bonzini         fadt = find_acpi_table_addr(FACP_SIGNATURE);
16372e3528SPaolo Bonzini         if (!fadt) {
17372e3528SPaolo Bonzini             return NULL;
18372e3528SPaolo Bonzini         }
19372e3528SPaolo Bonzini         return (void*)(ulong)fadt->firmware_ctrl;
20372e3528SPaolo Bonzini     }
21372e3528SPaolo Bonzini 
22372e3528SPaolo Bonzini     for(addr = 0xf0000; addr < 0x100000; addr += 16) {
23372e3528SPaolo Bonzini 	rsdp = (void*)addr;
24372e3528SPaolo Bonzini 	if (rsdp->signature == 0x2052545020445352LL)
25372e3528SPaolo Bonzini           break;
26372e3528SPaolo Bonzini     }
27372e3528SPaolo Bonzini     if (addr == 0x100000) {
28372e3528SPaolo Bonzini         printf("Can't find RSDP\n");
29372e3528SPaolo Bonzini         return 0;
30372e3528SPaolo Bonzini     }
31372e3528SPaolo Bonzini 
32372e3528SPaolo Bonzini     if (sig == RSDP_SIGNATURE) {
33372e3528SPaolo Bonzini         return rsdp;
34372e3528SPaolo Bonzini     }
35372e3528SPaolo Bonzini 
36372e3528SPaolo Bonzini     rsdt = (void*)(ulong)rsdp->rsdt_physical_address;
37372e3528SPaolo Bonzini     if (!rsdt || rsdt->signature != RSDT_SIGNATURE)
38372e3528SPaolo Bonzini         return 0;
39372e3528SPaolo Bonzini 
40372e3528SPaolo Bonzini     if (sig == RSDT_SIGNATURE) {
41372e3528SPaolo Bonzini         return rsdt;
42372e3528SPaolo Bonzini     }
43372e3528SPaolo Bonzini 
44372e3528SPaolo Bonzini     end = (void*)rsdt + rsdt->length;
45372e3528SPaolo Bonzini     for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) {
46372e3528SPaolo Bonzini         struct acpi_table *t = (void*)(ulong)rsdt->table_offset_entry[i];
47372e3528SPaolo Bonzini         if (t && t->signature == sig) {
48372e3528SPaolo Bonzini             return t;
49372e3528SPaolo Bonzini         }
50372e3528SPaolo Bonzini     }
51372e3528SPaolo Bonzini    return NULL;
52372e3528SPaolo Bonzini }
53