#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: acpi_table.c,v 1.2 2020/09/13 21:41:17 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/cpu.h>
#include <sys/device.h>
#include <uvm/uvm_extern.h>
#include <dev/acpi/acpireg.h>
#include <dev/acpi/acpivar.h>
#include <machine/acpi_machdep.h>
#include <arch/arm/acpi/acpi_table.h>
ACPI_STATUS
acpi_table_map(ACPI_PHYSICAL_ADDRESS pa, void **hdrp)
{
ACPI_TABLE_HEADER *header;
ACPI_STATUS rv;
UINT32 length;
rv = acpi_md_OsMapMemory(pa, sizeof(*header), (void **)&header);
if (ACPI_FAILURE(rv))
return rv;
length = le32toh(header->Length);
acpi_md_OsUnmapMemory(header, sizeof(*header));
return acpi_md_OsMapMemory(pa, length, hdrp);
}
void
acpi_table_unmap(ACPI_TABLE_HEADER *hdrp)
{
acpi_md_OsUnmapMemory(hdrp, le32toh(hdrp->Length));
}
ACPI_STATUS
acpi_table_find(const char *sig, void **hdrp)
{
ACPI_TABLE_RSDP *rsdp;
ACPI_TABLE_XSDT *xsdt;
ACPI_TABLE_HEADER *header;
ACPI_PHYSICAL_ADDRESS pa;
ACPI_STATUS rv;
pa = 0;
rv = acpi_md_OsMapMemory(acpi_md_OsGetRootPointer(), sizeof(*rsdp), (void **)&rsdp);
if (ACPI_FAILURE(rv))
return rv;
if (memcmp(rsdp->Signature, ACPI_SIG_RSDP, sizeof(rsdp->Signature)) == 0)
pa = le64toh(rsdp->XsdtPhysicalAddress);
acpi_md_OsUnmapMemory(rsdp, sizeof(*rsdp));
if (pa == 0)
return AE_NOT_FOUND;
rv = acpi_table_map(pa, (void **)&xsdt);
if (ACPI_FAILURE(rv))
return rv;
const u_int entries = (le32toh(xsdt->Header.Length) - sizeof(ACPI_TABLE_HEADER)) / ACPI_XSDT_ENTRY_SIZE;
for (u_int n = 0; n < entries; n++) {
rv = acpi_table_map(le64toh(xsdt->TableOffsetEntry[n]), (void **)&header);
if (ACPI_FAILURE(rv))
continue;
if (memcmp(header->Signature, sig, sizeof(header->Signature)) == 0) {
acpi_table_unmap((ACPI_TABLE_HEADER *)xsdt);
*hdrp = header;
return AE_OK;
}
}
acpi_table_unmap((ACPI_TABLE_HEADER *)xsdt);
return AE_NOT_FOUND;
}