ACPI_STATUS AcpiTbConvertToXsdt ( ACPI_TABLE_DESC *TableInfo) { ACPI_SIZE TableSize; UINT32 i; XSDT_DESCRIPTOR *NewTable; ACPI_FUNCTION_ENTRY (); /* Compute size of the converted XSDT */ TableSize = ((ACPI_SIZE) AcpiGbl_RsdtTableCount * sizeof (UINT64)) + sizeof (ACPI_TABLE_HEADER); /* Allocate an XSDT */ NewTable = ACPI_MEM_CALLOCATE (TableSize); if (!NewTable) { return (AE_NO_MEMORY); } /* Copy the header and set the length */ ACPI_MEMCPY (NewTable, TableInfo->Pointer, sizeof (ACPI_TABLE_HEADER)); NewTable->Header.Length = (UINT32) TableSize; /* Copy the table pointers */ for (i = 0; i < AcpiGbl_RsdtTableCount; i++) { if (AcpiGbl_RSDP->Revision < 2) { ACPI_STORE_ADDRESS (NewTable->TableOffsetEntry[i], ((RSDT_DESCRIPTOR_REV1 *) TableInfo->Pointer)->TableOffsetEntry[i]); } else { NewTable->TableOffsetEntry[i] = ((XSDT_DESCRIPTOR *) TableInfo->Pointer)->TableOffsetEntry[i]; } } /* Delete the original table (either mapped or in a buffer) */ AcpiTbDeleteSingleTable (TableInfo); /* Point the table descriptor to the new table */ TableInfo->Pointer = (ACPI_TABLE_HEADER *) NewTable; TableInfo->Length = TableSize; TableInfo->Allocation = ACPI_MEM_ALLOCATED; return (AE_OK); }
static ACPI_STATUS AeLocalLoadTable ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status = AE_OK; /* ACPI_TABLE_DESC TableInfo; */ ACPI_FUNCTION_TRACE (AeLocalLoadTable); #if 0 if (!Table) { return_ACPI_STATUS (AE_BAD_PARAMETER); } TableInfo.Pointer = Table; Status = AcpiTbRecognizeTable (&TableInfo, ACPI_TABLE_ALL); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Install the new table into the local data structures */ Status = AcpiTbInitTableDescriptor (&TableInfo); if (ACPI_FAILURE (Status)) { if (Status == AE_ALREADY_EXISTS) { /* Table already exists, no error */ Status = AE_OK; } /* Free table allocated by AcpiTbGetTable */ AcpiTbDeleteSingleTable (&TableInfo); return_ACPI_STATUS (Status); } #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) Status = AcpiNsLoadTable (TableInfo.InstalledDesc, AcpiGbl_RootNode); if (ACPI_FAILURE (Status)) { /* Uninstall table and free the buffer */ AcpiTbDeleteTablesByType (ACPI_TABLE_ID_DSDT); return_ACPI_STATUS (Status); } #endif #endif return_ACPI_STATUS (Status); }
ACPI_TABLE_DESC * AcpiTbUninstallTable ( ACPI_TABLE_DESC *TableDesc) { ACPI_TABLE_DESC *NextDesc; ACPI_FUNCTION_TRACE_PTR (TbUninstallTable, TableDesc); if (!TableDesc) { return_PTR (NULL); } /* Unlink the descriptor from the doubly linked list */ if (TableDesc->Prev) { TableDesc->Prev->Next = TableDesc->Next; } else { /* Is first on list, update list head */ AcpiGbl_TableLists[TableDesc->Type].Next = TableDesc->Next; } if (TableDesc->Next) { TableDesc->Next->Prev = TableDesc->Prev; } /* Free the memory allocated for the table itself */ AcpiTbDeleteSingleTable (TableDesc); /* Free the owner ID associated with this table */ AcpiUtReleaseOwnerId (&TableDesc->OwnerId); /* Free the table descriptor */ NextDesc = TableDesc->Next; ACPI_FREE (TableDesc); /* Return pointer to the next descriptor */ return_PTR (NextDesc); }
/******************************************************************************* * * FUNCTION: AeLocalLoadTable * * PARAMETERS: TablePtr - pointer to a buffer containing the entire * table to be loaded * * RETURN: Status * * DESCRIPTION: This function is called to load a table from the caller's * buffer. The buffer must contain an entire ACPI Table including * a valid header. The header fields will be verified, and if it * is determined that the table is invalid, the call will fail. * * If the call fails an appropriate status will be returned. * ******************************************************************************/ #if 0 /* XXX unused -- [email protected] */ ACPI_STATUS AeLocalLoadTable ( ACPI_TABLE_HEADER *TablePtr) { ACPI_STATUS Status; ACPI_TABLE_DESC TableInfo; FUNCTION_TRACE ("AeLocalLoadTable"); if (!TablePtr) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Install the new table into the local data structures */ TableInfo.Pointer = TablePtr; Status = AcpiTbInstallTable (NULL, &TableInfo); if (ACPI_FAILURE (Status)) { /* Free table allocated by AcpiTbGetTable */ AcpiTbDeleteSingleTable (&TableInfo); return_ACPI_STATUS (Status); } #ifndef PARSER_ONLY Status = AcpiNsLoadTable (TableInfo.InstalledDesc, AcpiGbl_RootNode); if (ACPI_FAILURE (Status)) { /* Uninstall table and free the buffer */ AcpiTbUninstallTable (TableInfo.InstalledDesc); return_ACPI_STATUS (Status); } #endif return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiTbConvertTableFadt (void) { FADT_DESCRIPTOR_REV2 *LocalFadt; ACPI_TABLE_DESC *TableDesc; ACPI_FUNCTION_TRACE ("TbConvertTableFadt"); /* * AcpiGbl_FADT is valid * Allocate and zero the 2.0 FADT buffer */ LocalFadt = ACPI_MEM_CALLOCATE (sizeof (FADT_DESCRIPTOR_REV2)); if (LocalFadt == NULL) { return_ACPI_STATUS (AE_NO_MEMORY); } /* * FADT length and version validation. The table must be at least as * long as the version 1.0 FADT */ if (AcpiGbl_FADT->Header.Length < sizeof (FADT_DESCRIPTOR_REV1)) { ACPI_REPORT_ERROR (("Invalid FADT table length: 0x%X\n", AcpiGbl_FADT->Header.Length)); return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); } if (AcpiGbl_FADT->Header.Revision >= FADT2_REVISION_ID) { if (AcpiGbl_FADT->Header.Length < sizeof (FADT_DESCRIPTOR_REV2)) { /* Length is too short to be a V2.0 table */ ACPI_REPORT_WARNING (("Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n", AcpiGbl_FADT->Header.Length, AcpiGbl_FADT->Header.Revision)); AcpiTbConvertFadt1 (LocalFadt, (void *) AcpiGbl_FADT); } else { /* Valid V2.0 table */ AcpiTbConvertFadt2 (LocalFadt, AcpiGbl_FADT); } } else { /* Valid V1.0 table */ AcpiTbConvertFadt1 (LocalFadt, (void *) AcpiGbl_FADT); } /* * Global FADT pointer will point to the new common V2.0 FADT */ AcpiGbl_FADT = LocalFadt; AcpiGbl_FADT->Header.Length = sizeof (FADT_DESCRIPTOR); /* Free the original table */ TableDesc = &AcpiGbl_AcpiTables[ACPI_TABLE_FADT]; AcpiTbDeleteSingleTable (TableDesc); /* Install the new table */ TableDesc->Pointer = (ACPI_TABLE_HEADER *) AcpiGbl_FADT; TableDesc->Allocation = ACPI_MEM_ALLOCATED; TableDesc->Length = sizeof (FADT_DESCRIPTOR_REV2); /* Dump the entire FADT */ ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Hex dump of common internal FADT, size %d (%X)\n", AcpiGbl_FADT->Header.Length, AcpiGbl_FADT->Header.Length)); ACPI_DUMP_BUFFER ((UINT8 *) (AcpiGbl_FADT), AcpiGbl_FADT->Header.Length); return_ACPI_STATUS (AE_OK); }
ACPI_STATUS AcpiTbConvertTableFadt ( void) { FADT_DESCRIPTOR *LocalFadt; ACPI_TABLE_DESC *TableDesc; ACPI_FUNCTION_TRACE (TbConvertTableFadt); /* * AcpiGbl_FADT is valid. Validate the FADT length. The table must be * at least as long as the version 1.0 FADT */ if (AcpiGbl_FADT->Length < sizeof (FADT_DESCRIPTOR_REV1)) { ACPI_ERROR ((AE_INFO, "FADT is invalid, too short: 0x%X", AcpiGbl_FADT->Length)); return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); } /* Allocate buffer for the ACPI 2.0(+) FADT */ LocalFadt = ACPI_ALLOCATE_ZEROED (sizeof (FADT_DESCRIPTOR)); if (!LocalFadt) { return_ACPI_STATUS (AE_NO_MEMORY); } if (AcpiGbl_FADT->Revision >= FADT2_REVISION_ID) { if (AcpiGbl_FADT->Length < sizeof (FADT_DESCRIPTOR)) { /* Length is too short to be a V2.0 table */ ACPI_WARNING ((AE_INFO, "Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table", AcpiGbl_FADT->Length, AcpiGbl_FADT->Revision)); AcpiTbConvertFadt1 (LocalFadt, (void *) AcpiGbl_FADT); } else { /* Valid V2.0 table */ AcpiTbConvertFadt2 (LocalFadt, AcpiGbl_FADT); } } else { /* Valid V1.0 table */ AcpiTbConvertFadt1 (LocalFadt, (void *) AcpiGbl_FADT); } /* Global FADT pointer will point to the new common V2.0 FADT */ AcpiGbl_FADT = LocalFadt; AcpiGbl_FADT->Length = sizeof (FADT_DESCRIPTOR); /* Free the original table */ TableDesc = AcpiGbl_TableLists[ACPI_TABLE_ID_FADT].Next; AcpiTbDeleteSingleTable (TableDesc); /* Install the new table */ TableDesc->Pointer = ACPI_CAST_PTR (ACPI_TABLE_HEADER, AcpiGbl_FADT); TableDesc->Allocation = ACPI_MEM_ALLOCATED; TableDesc->Length = sizeof (FADT_DESCRIPTOR); /* Dump the entire FADT */ ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Hex dump of common internal FADT, size %d (%X)\n", AcpiGbl_FADT->Length, AcpiGbl_FADT->Length)); ACPI_DUMP_BUFFER (ACPI_CAST_PTR (UINT8, AcpiGbl_FADT), AcpiGbl_FADT->Length); return_ACPI_STATUS (AE_OK); }
ACPI_STATUS AcpiLoadTable ( ACPI_TABLE_HEADER *TablePtr) { ACPI_STATUS Status; ACPI_TABLE_DESC TableInfo; ACPI_POINTER Address; ACPI_FUNCTION_TRACE ("AcpiLoadTable"); if (!TablePtr) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Copy the table to a local buffer */ Address.PointerType = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; Address.Pointer.Logical = TablePtr; Status = AcpiTbGetTableBody (&Address, TablePtr, &TableInfo); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Install the new table into the local data structures */ Status = AcpiTbInstallTable (&TableInfo); if (ACPI_FAILURE (Status)) { /* Free table allocated by AcpiTbGetTableBody */ AcpiTbDeleteSingleTable (&TableInfo); return_ACPI_STATUS (Status); } /* Convert the table to common format if necessary */ switch (TableInfo.Type) { case ACPI_TABLE_FADT: Status = AcpiTbConvertTableFadt (); break; case ACPI_TABLE_FACS: Status = AcpiTbBuildCommonFacs (&TableInfo); break; default: /* Load table into namespace if it contains executable AML */ Status = AcpiNsLoadTable (TableInfo.InstalledDesc, AcpiGbl_RootNode); break; } if (ACPI_FAILURE (Status)) { /* Uninstall table and free the buffer */ (void) AcpiTbUninstallTable (TableInfo.InstalledDesc); } return_ACPI_STATUS (Status); }