xref: /kvm-unit-tests/lib/acpi.c (revision 0d99dcec7f05126f27397e0f73c2ab5b8f238f5d)
1 #include "libcflat.h"
2 #include "acpi.h"
3 
4 #ifdef CONFIG_EFI
5 struct rsdp_descriptor *efi_rsdp = NULL;
6 
7 void set_efi_rsdp(struct rsdp_descriptor *rsdp)
8 {
9 	efi_rsdp = rsdp;
10 }
11 
12 static struct rsdp_descriptor *get_rsdp(void)
13 {
14 	if (efi_rsdp == NULL) {
15 		printf("Can't find RSDP from UEFI, maybe set_efi_rsdp() was not called\n");
16 	}
17 	return efi_rsdp;
18 }
19 #else
20 static struct rsdp_descriptor *get_rsdp(void)
21 {
22 	struct rsdp_descriptor *rsdp;
23 	unsigned long addr;
24 
25 	for (addr = 0xe0000; addr < 0x100000; addr += 16) {
26 		rsdp = (void *)addr;
27 		if (rsdp->signature == RSDP_SIGNATURE_8BYTE)
28 			break;
29 	}
30 
31 	if (addr == 0x100000) {
32 		return NULL;
33 	}
34 
35 	return rsdp;
36 }
37 #endif /* CONFIG_EFI */
38 
39 void* find_acpi_table_addr(u32 sig)
40 {
41     struct rsdp_descriptor *rsdp;
42     struct rsdt_descriptor_rev1 *rsdt;
43     void *end;
44     int i;
45 
46     /* FACS is special... */
47     if (sig == FACS_SIGNATURE) {
48         struct fadt_descriptor_rev1 *fadt;
49         fadt = find_acpi_table_addr(FACP_SIGNATURE);
50         if (!fadt) {
51             return NULL;
52         }
53         return (void*)(ulong)fadt->firmware_ctrl;
54     }
55 
56     rsdp = get_rsdp();
57     if (rsdp == NULL) {
58         printf("Can't find RSDP\n");
59         return 0;
60     }
61 
62     if (sig == RSDP_SIGNATURE) {
63         return rsdp;
64     }
65 
66     rsdt = (void*)(ulong)rsdp->rsdt_physical_address;
67     if (!rsdt || rsdt->signature != RSDT_SIGNATURE)
68         return 0;
69 
70     if (sig == RSDT_SIGNATURE) {
71         return rsdt;
72     }
73 
74     end = (void*)rsdt + rsdt->length;
75     for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) {
76         struct acpi_table *t = (void*)(ulong)rsdt->table_offset_entry[i];
77         if (t && t->signature == sig) {
78             return t;
79         }
80     }
81    return NULL;
82 }
83