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