1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Utility functions for ACPI 4 * 5 * Copyright 2023 Google LLC 6 */ 7 8#include <mapmem.h> 9#include <acpi/acpi_table.h> 10#include <asm/global_data.h> 11 12DECLARE_GLOBAL_DATA_PTR; 13 14struct acpi_table_header *acpi_find_table(const char *sig) 15{ 16 struct acpi_rsdp *rsdp; 17 struct acpi_rsdt *rsdt; 18 struct acpi_xsdt *xsdt; 19 int len, i, count; 20 21 rsdp = map_sysmem(gd_acpi_start(), 0); 22 if (!rsdp) 23 return NULL; 24 if (rsdp->xsdt_address) { 25 xsdt = nomap_sysmem(rsdp->xsdt_address, 0); 26 len = xsdt->header.length - sizeof(xsdt->header); 27 count = len / sizeof(u64); 28 } else { 29 if (!rsdp->rsdt_address) 30 return NULL; 31 rsdt = nomap_sysmem(rsdp->rsdt_address, 0); 32 len = rsdt->header.length - sizeof(rsdt->header); 33 count = len / sizeof(u32); 34 } 35 for (i = 0; i < count; i++) { 36 struct acpi_table_header *hdr; 37 38 if (rsdp->xsdt_address) 39 hdr = nomap_sysmem(xsdt->entry[i], 0); 40 else 41 hdr = nomap_sysmem(rsdt->entry[i], 0); 42 if (!memcmp(hdr->signature, sig, ACPI_NAME_LEN)) 43 return hdr; 44 if (!memcmp(hdr->signature, "FACP", ACPI_NAME_LEN)) { 45 struct acpi_fadt *fadt = (struct acpi_fadt *)hdr; 46 47 if (!memcmp(sig, "DSDT", ACPI_NAME_LEN)) { 48 void *dsdt; 49 50 if (fadt->header.revision >= 3 && fadt->x_dsdt) 51 dsdt = nomap_sysmem(fadt->x_dsdt, 0); 52 else if (fadt->dsdt) 53 dsdt = nomap_sysmem(fadt->dsdt, 0); 54 else 55 dsdt = NULL; 56 return dsdt; 57 } 58 59 if (!memcmp(sig, "FACS", ACPI_NAME_LEN)) { 60 void *facs; 61 62 if (fadt->header.revision >= 3 && 63 fadt->x_firmware_ctrl) 64 facs = nomap_sysmem(fadt->x_firmware_ctrl, 0); 65 else if (fadt->firmware_ctrl) 66 facs = nomap_sysmem(fadt->firmware_ctrl, 0); 67 else 68 facs = NULL; 69 return facs; 70 } 71 } 72 } 73 74 return NULL; 75} 76