void * acpi_find_table(const char *sig) { ACPI_PHYSICAL_ADDRESS rsdp_ptr; ACPI_TABLE_RSDP *rsdp; ACPI_TABLE_XSDT *xsdt; ACPI_TABLE_HEADER *table; UINT64 addr; u_int i, count; if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0) return (NULL); rsdp = (ACPI_TABLE_RSDP *)IA64_PHYS_TO_RR7(rsdp_ptr); xsdt = (ACPI_TABLE_XSDT *)IA64_PHYS_TO_RR7(rsdp->XsdtPhysicalAddress); count = (UINT64 *)((char *)xsdt + xsdt->Header.Length) - xsdt->TableOffsetEntry; for (i = 0; i < count; i++) { addr = xsdt->TableOffsetEntry[i]; table = (ACPI_TABLE_HEADER *)IA64_PHYS_TO_RR7(addr); if (strncmp(table->Signature, sig, ACPI_NAME_SIZE) != 0) continue; if (ACPI_FAILURE(AcpiTbChecksum((void *)table, table->Length))) continue; return (table); } return (NULL); }
ACPI_STATUS AcpiInitializeTables ( ACPI_TABLE_DESC *InitialTableArray, UINT32 InitialTableCount, BOOLEAN AllowResize) { ACPI_PHYSICAL_ADDRESS RsdpAddress; ACPI_STATUS Status; ACPI_FUNCTION_TRACE (AcpiInitializeTables); /* * Setup the Root Table Array and allocate the table array * if requested */ if (!InitialTableArray) { Status = AcpiAllocateRootTable (InitialTableCount); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } else { /* Root Table Array has been statically allocated by the host */ memset (InitialTableArray, 0, (ACPI_SIZE) InitialTableCount * sizeof (ACPI_TABLE_DESC)); AcpiGbl_RootTableList.Tables = InitialTableArray; AcpiGbl_RootTableList.MaxTableCount = InitialTableCount; AcpiGbl_RootTableList.Flags = ACPI_ROOT_ORIGIN_UNKNOWN; if (AllowResize) { AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE; } } /* Get the address of the RSDP */ RsdpAddress = AcpiOsGetRootPointer (); if (!RsdpAddress) { return_ACPI_STATUS (AE_NOT_FOUND); } /* * Get the root table (RSDT or XSDT) and extract all entries to the local * Root Table Array. This array contains the information of the RSDT/XSDT * in a common, more useable format. */ Status = AcpiTbParseRootTable (RsdpAddress); return_ACPI_STATUS (Status); }
static PyObject *bits_acpi_get_root_pointer(PyObject *self, PyObject *args) { ACPI_TABLE_RSDP *rsdp; if (acpica_init() != GRUB_ERR_NONE) return PyErr_Format(PyExc_RuntimeError, "ACPICA module failed to initialize."); rsdp = (ACPI_TABLE_RSDP *)AcpiOsGetRootPointer(); if (rsdp) return Py_BuildValue("k", (unsigned long)rsdp); return Py_BuildValue(""); }
/* * Count the number of local SAPIC entries in the APIC table. Every enabled * entry corresponds to a processor. */ int ia64_count_cpus(void) { ACPI_PHYSICAL_ADDRESS rsdp_ptr; ACPI_MADT_LOCAL_SAPIC *entry; ACPI_TABLE_MADT *table; ACPI_TABLE_RSDP *rsdp; ACPI_TABLE_XSDT *xsdt; char *end, *p; int cpus, t, tables; if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0) return (0); rsdp = (ACPI_TABLE_RSDP *)IA64_PHYS_TO_RR7(rsdp_ptr); xsdt = (ACPI_TABLE_XSDT *)IA64_PHYS_TO_RR7(rsdp->XsdtPhysicalAddress); tables = (UINT64 *)((char *)xsdt + xsdt->Header.Length) - xsdt->TableOffsetEntry; cpus = 0; for (t = 0; t < tables; t++) { table = (ACPI_TABLE_MADT *) IA64_PHYS_TO_RR7(xsdt->TableOffsetEntry[t]); if (strncmp(table->Header.Signature, ACPI_SIG_MADT, ACPI_NAME_SIZE) != 0 || ACPI_FAILURE(AcpiTbChecksum((void *)table, table->Header.Length))) continue; end = (char *)table + table->Header.Length; p = (char *)(table + 1); while (p < end) { entry = (ACPI_MADT_LOCAL_SAPIC *)p; if (entry->Header.Type == ACPI_MADT_TYPE_LOCAL_SAPIC && (entry->LapicFlags & ACPI_MADT_ENABLED)) cpus++; p += entry->Header.Length; } } return (cpus); }
static PyObject *bits_acpi_get_rsdt(PyObject *self, PyObject *args) { ACPI_TABLE_RSDP *rsdp; ACPI_TABLE_RSDT *rsdt; if (acpica_init() != GRUB_ERR_NONE) return PyErr_Format(PyExc_RuntimeError, "ACPICA module failed to initialize."); rsdp = (ACPI_TABLE_RSDP *)AcpiOsGetRootPointer(); if (rsdp) { rsdt = (ACPI_TABLE_RSDT *)(unsigned long)rsdp->RsdtPhysicalAddress; if (rsdt) return Py_BuildValue("s#", rsdt, (Py_ssize_t)rsdt->Header.Length); } return Py_BuildValue(""); }
static PyObject *bits_acpi_get_rsdp(PyObject *self, PyObject *args) { ACPI_TABLE_RSDP *rsdp; Py_ssize_t length = 0; if (acpica_init() != GRUB_ERR_NONE) return PyErr_Format(PyExc_RuntimeError, "ACPICA module failed to initialize."); rsdp = (ACPI_TABLE_RSDP *)AcpiOsGetRootPointer(); if (rsdp) { if (rsdp->Revision == 0) length = sizeof(ACPI_RSDP_COMMON); else if (rsdp->Revision >= 2) length = rsdp->Length; if (length) return Py_BuildValue("s#", rsdp, length); } return Py_BuildValue(""); }
static PyObject *bits_acpi_get_xsdt(PyObject *self, PyObject *args) { ACPI_TABLE_RSDP *rsdp; ACPI_TABLE_XSDT *xsdt; if (acpica_init() != GRUB_ERR_NONE) return PyErr_Format(PyExc_RuntimeError, "ACPICA module failed to initialize."); rsdp = (ACPI_TABLE_RSDP *)AcpiOsGetRootPointer(); if (rsdp) { if (rsdp->Revision >= 2) { #if defined(GRUB_TARGET_CPU_I386) if (rsdp->XsdtPhysicalAddress > GRUB_UINT_MAX) return PyErr_Format(PyExc_RuntimeError, "XSDT located above 4G; cannot access on 32-bit"); #endif xsdt = (ACPI_TABLE_XSDT *)(unsigned long)rsdp->XsdtPhysicalAddress; if (xsdt) return Py_BuildValue("s#", xsdt, (Py_ssize_t)xsdt->Header.Length); } } return Py_BuildValue(""); }
void ia64_probe_sapics(void) { ACPI_PHYSICAL_ADDRESS rsdp_ptr; ACPI_SUBTABLE_HEADER *entry; ACPI_TABLE_MADT *table; ACPI_TABLE_RSDP *rsdp; ACPI_TABLE_XSDT *xsdt; char *end, *p; int t, tables; if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0) return; rsdp = (ACPI_TABLE_RSDP *)IA64_PHYS_TO_RR7(rsdp_ptr); xsdt = (ACPI_TABLE_XSDT *)IA64_PHYS_TO_RR7(rsdp->XsdtPhysicalAddress); tables = (UINT64 *)((char *)xsdt + xsdt->Header.Length) - xsdt->TableOffsetEntry; for (t = 0; t < tables; t++) { table = (ACPI_TABLE_MADT *) IA64_PHYS_TO_RR7(xsdt->TableOffsetEntry[t]); if (bootverbose) printf("Table '%c%c%c%c' at %p\n", table->Header.Signature[0], table->Header.Signature[1], table->Header.Signature[2], table->Header.Signature[3], table); if (strncmp(table->Header.Signature, ACPI_SIG_MADT, ACPI_NAME_SIZE) != 0 || ACPI_FAILURE(AcpiTbChecksum((void *)table, table->Header.Length))) continue; /* Save the address of the processor interrupt block. */ if (bootverbose) printf("\tLocal APIC address=0x%x\n", table->Address); ia64_lapic_addr = table->Address; end = (char *)table + table->Header.Length; p = (char *)(table + 1); while (p < end) { entry = (ACPI_SUBTABLE_HEADER *)p; if (bootverbose) print_entry(entry); switch (entry->Type) { case ACPI_MADT_TYPE_IO_SAPIC: { ACPI_MADT_IO_SAPIC *sapic = (ACPI_MADT_IO_SAPIC *)entry; sapic_create(sapic->Id, sapic->GlobalIrqBase, sapic->Address); break; } case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: { ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)entry; ia64_lapic_addr = lapic->Address; break; } #ifdef SMP case ACPI_MADT_TYPE_LOCAL_SAPIC: { ACPI_MADT_LOCAL_SAPIC *sapic = (ACPI_MADT_LOCAL_SAPIC *)entry; if (sapic->LapicFlags & ACPI_MADT_ENABLED) cpu_mp_add(sapic->ProcessorId, sapic->Id, sapic->Eid); break; } #endif default: break; } p += entry->Length; } } }
ACPI_STATUS AcpiGetFirmwareTable ( ACPI_STRING Signature, UINT32 Instance, UINT32 Flags, ACPI_TABLE_HEADER **TablePointer) { ACPI_POINTER RsdpAddress; ACPI_POINTER Address; ACPI_STATUS Status; ACPI_TABLE_HEADER Header; ACPI_TABLE_DESC TableInfo; ACPI_TABLE_DESC RsdtInfo; UINT32 TableCount; UINT32 i; UINT32 j; ACPI_FUNCTION_TRACE ("AcpiGetFirmwareTable"); /* * Ensure that at least the table manager is initialized. We don't * require that the entire ACPI subsystem is up for this interface */ /* * If we have a buffer, we must have a length too */ if ((Instance == 0) || (!Signature) || (!TablePointer)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } RsdtInfo.Pointer = NULL; if (!AcpiGbl_RSDP) { /* Get the RSDP */ Status = AcpiOsGetRootPointer (Flags, &RsdpAddress); if (ACPI_FAILURE (Status)) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP not found\n")); return_ACPI_STATUS (AE_NO_ACPI_TABLES); } /* Map and validate the RSDP */ if ((Flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { Status = AcpiOsMapMemory (RsdpAddress.Pointer.Physical, sizeof (RSDP_DESCRIPTOR), (void **) &AcpiGbl_RSDP); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } else { AcpiGbl_RSDP = RsdpAddress.Pointer.Logical; } /* * The signature and checksum must both be correct */ if (ACPI_STRNCMP ((char *) AcpiGbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) { /* Nope, BAD Signature */ return_ACPI_STATUS (AE_BAD_SIGNATURE); } if (AcpiTbChecksum (AcpiGbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { /* Nope, BAD Checksum */ return_ACPI_STATUS (AE_BAD_CHECKSUM); } } /* Get the RSDT and validate it */ AcpiTbGetRsdtAddress (&Address); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP located at %p, RSDT physical=%8.8X%8.8X \n", AcpiGbl_RSDP, ACPI_HIDWORD (Address.Pointer.Value), ACPI_LODWORD (Address.Pointer.Value))); /* Insert ProcessorMode flags */ Address.PointerType |= Flags; Status = AcpiTbGetTable (&Address, &RsdtInfo); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } Status = AcpiTbValidateRsdt (RsdtInfo.Pointer); if (ACPI_FAILURE (Status)) { goto Cleanup; } /* Get the number of table pointers within the RSDT */ TableCount = AcpiTbGetTableCount (AcpiGbl_RSDP, RsdtInfo.Pointer); Address.PointerType = AcpiGbl_TableFlags | Flags; /* * Search the RSDT/XSDT for the correct instance of the * requested table */ for (i = 0, j = 0; i < TableCount; i++) { /* Get the next table pointer, handle RSDT vs. XSDT */ if (AcpiGbl_RSDP->Revision < 2) { Address.Pointer.Value = ((RSDT_DESCRIPTOR *) RsdtInfo.Pointer)->TableOffsetEntry[i]; } else { Address.Pointer.Value = ACPI_GET_ADDRESS ( ((XSDT_DESCRIPTOR *) RsdtInfo.Pointer)->TableOffsetEntry[i]); } /* Get the table header */ Status = AcpiTbGetTableHeader (&Address, &Header); if (ACPI_FAILURE (Status)) { goto Cleanup; } /* Compare table signatures and table instance */ if (!ACPI_STRNCMP (Header.Signature, Signature, ACPI_NAME_SIZE)) { /* An instance of the table was found */ j++; if (j >= Instance) { /* Found the correct instance, get the entire table */ Status = AcpiTbGetTableBody (&Address, &Header, &TableInfo); if (ACPI_FAILURE (Status)) { goto Cleanup; } *TablePointer = TableInfo.Pointer; goto Cleanup; } } } /* Did not find the table */ Status = AE_NOT_EXIST; Cleanup: AcpiOsUnmapMemory (RsdtInfo.Pointer, (ACPI_SIZE) RsdtInfo.Pointer->Length); return_ACPI_STATUS (Status); }
/* * Return the physical address of the requested table or zero if one * is not found. */ vm_paddr_t acpi_find_table(const char *sig) { ACPI_PHYSICAL_ADDRESS rsdp_ptr; ACPI_TABLE_RSDP *rsdp; ACPI_TABLE_XSDT *xsdt; ACPI_TABLE_HEADER *table; vm_paddr_t addr; int i, count; if (resource_disabled("acpi", 0)) return (0); /* * Map in the RSDP. Since ACPI uses AcpiOsMapMemory() which in turn * calls pmap_mapbios() to find the RSDP, we assume that we can use * pmap_mapbios() to map the RSDP. */ if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0) return (0); rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP)); if (rsdp == NULL) { if (bootverbose) printf("ACPI: Failed to map RSDP\n"); return (0); } addr = 0; if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) { /* * AcpiOsGetRootPointer only verifies the checksum for * the version 1.0 portion of the RSDP. Version 2.0 has * an additional checksum that we verify first. */ if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) { if (bootverbose) printf("ACPI: RSDP failed extended checksum\n"); return (0); } xsdt = map_table(rsdp->XsdtPhysicalAddress, 2, ACPI_SIG_XSDT); if (xsdt == NULL) { if (bootverbose) printf("ACPI: Failed to map XSDT\n"); pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP)); return (0); } count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) / sizeof(UINT64); for (i = 0; i < count; i++) if (probe_table(xsdt->TableOffsetEntry[i], sig)) { addr = xsdt->TableOffsetEntry[i]; break; } acpi_unmap_table(xsdt); } pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP)); if (addr == 0) { if (bootverbose) printf("ACPI: No %s table found\n", sig); return (0); } if (bootverbose) printf("%s: Found table at 0x%jx\n", sig, (uintmax_t)addr); /* * Verify that we can map the full table and that its checksum is * correct, etc. */ table = map_table(addr, 0, sig); if (table == NULL) return (0); acpi_unmap_table(table); return (addr); }
ACPI_STATUS AcpiLoadTables (void) { ACPI_POINTER RsdpAddress; ACPI_STATUS Status; ACPI_FUNCTION_TRACE ("AcpiLoadTables"); /* Get the RSDP */ Status = AcpiOsGetRootPointer (ACPI_LOGICAL_ADDRESSING, &RsdpAddress); if (ACPI_FAILURE (Status)) { ACPI_REPORT_ERROR (("AcpiLoadTables: Could not get RSDP, %s\n", AcpiFormatException (Status))); goto ErrorExit; } /* Map and validate the RSDP */ AcpiGbl_TableFlags = RsdpAddress.PointerType; Status = AcpiTbVerifyRsdp (&RsdpAddress); if (ACPI_FAILURE (Status)) { ACPI_REPORT_ERROR (("AcpiLoadTables: RSDP Failed validation: %s\n", AcpiFormatException (Status))); goto ErrorExit; } /* Get the RSDT via the RSDP */ Status = AcpiTbGetTableRsdt (); if (ACPI_FAILURE (Status)) { ACPI_REPORT_ERROR (("AcpiLoadTables: Could not load RSDT: %s\n", AcpiFormatException (Status))); goto ErrorExit; } /* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */ Status = AcpiTbGetRequiredTables (); if (ACPI_FAILURE (Status)) { ACPI_REPORT_ERROR (("AcpiLoadTables: Error getting required tables (DSDT/FADT/FACS): %s\n", AcpiFormatException (Status))); goto ErrorExit; } ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); /* Load the namespace from the tables */ Status = AcpiNsLoadNamespace (); if (ACPI_FAILURE (Status)) { ACPI_REPORT_ERROR (("AcpiLoadTables: Could not load namespace: %s\n", AcpiFormatException (Status))); goto ErrorExit; } return_ACPI_STATUS (AE_OK); ErrorExit: ACPI_REPORT_ERROR (("AcpiLoadTables: Could not load tables: %s\n", AcpiFormatException (Status))); return_ACPI_STATUS (Status); }
/* * Look for an ACPI Multiple APIC Description Table ("APIC") */ static int madt_probe(void) { ACPI_POINTER rsdp_ptr; RSDP_DESCRIPTOR *rsdp; RSDT_DESCRIPTOR *rsdt; XSDT_DESCRIPTOR *xsdt; int i, count; if (resource_disabled("acpi", 0)) return (ENXIO); /* * Map in the RSDP. Since ACPI uses AcpiOsMapMemory() which in turn * calls pmap_mapdev() to find the RSDP, we assume that we can use * pmap_mapdev() to map the RSDP. */ if (AcpiOsGetRootPointer(ACPI_LOGICAL_ADDRESSING, &rsdp_ptr) != AE_OK) return (ENXIO); #ifdef __i386__ KASSERT(rsdp_ptr.Pointer.Physical < KERNLOAD, ("RSDP too high")); #endif rsdp = pmap_mapdev(rsdp_ptr.Pointer.Physical, sizeof(RSDP_DESCRIPTOR)); if (rsdp == NULL) { if (bootverbose) printf("MADT: Failed to map RSDP\n"); return (ENXIO); } /* * For ACPI < 2.0, use the RSDT. For ACPI >= 2.0, use the XSDT. * We map the XSDT and RSDT at page 1 in the crashdump area. * Page 0 is used to map in the headers of candidate ACPI tables. */ if (rsdp->Revision >= 2) { xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 1, XSDT_SIG); if (xsdt == NULL) { if (bootverbose) printf("MADT: Failed to map XSDT\n"); return (ENXIO); } count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) / sizeof(UINT64); for (i = 0; i < count; i++) if (madt_probe_table(xsdt->TableOffsetEntry[i])) break; madt_unmap_table(xsdt); } else { rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 1, RSDT_SIG); if (rsdt == NULL) { if (bootverbose) printf("MADT: Failed to map RSDT\n"); return (ENXIO); } count = (rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) / sizeof(UINT32); for (i = 0; i < count; i++) if (madt_probe_table(rsdt->TableOffsetEntry[i])) break; madt_unmap_table(rsdt); } pmap_unmapdev((vm_offset_t)rsdp, sizeof(RSDP_DESCRIPTOR)); if (madt_physaddr == 0) { if (bootverbose) printf("MADT: No MADT table found\n"); return (ENXIO); } if (bootverbose) printf("MADT: Found table at 0x%jx\n", (uintmax_t)madt_physaddr); return (0); }