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