ACPI_STATUS AdGetLocalTables ( void) { ACPI_STATUS Status; ACPI_TABLE_HEADER TableHeader; ACPI_TABLE_HEADER *NewTable; UINT32 TableIndex; /* Get the DSDT via table override */ ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT); AcpiOsTableOverride (&TableHeader, &NewTable); if (!NewTable) { fprintf (stderr, "Could not obtain DSDT\n"); return (AE_NO_ACPI_TABLES); } AdWriteTable (NewTable, NewTable->Length, ACPI_SIG_DSDT, NewTable->OemTableId); /* Store DSDT in the Table Manager */ Status = AcpiTbStoreTable (0, NewTable, NewTable->Length, 0, &TableIndex); if (ACPI_FAILURE (Status)) { fprintf (stderr, "Could not store DSDT\n"); return (AE_NO_ACPI_TABLES); } return (AE_OK); }
ACPI_STATUS AcpiTbAddTable ( ACPI_TABLE_DESC *TableDesc, UINT32 *TableIndex) { UINT32 i; ACPI_STATUS Status = AE_OK; ACPI_FUNCTION_TRACE (TbAddTable); if (!TableDesc->Pointer) { Status = AcpiTbVerifyTable (TableDesc); if (ACPI_FAILURE (Status) || !TableDesc->Pointer) { return_ACPI_STATUS (Status); } } /* * Validate the incoming table signature. * * 1) Originally, we checked the table signature for "SSDT" or "PSDT". * 2) We added support for OEMx tables, signature "OEM". * 3) Valid tables were encountered with a null signature, so we just * gave up on validating the signature, (05/2008). * 4) We encountered non-AML tables such as the MADT, which caused * interpreter errors and kernel faults. So now, we once again allow * only "SSDT", "OEMx", and now, also a null signature. (05/2011). */ if ((TableDesc->Pointer->Signature[0] != 0x00) && (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) && (ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3))) { ACPI_BIOS_ERROR ((AE_INFO, "Table has invalid signature [%4.4s] (0x%8.8X), " "must be SSDT or OEMx", AcpiUtValidAcpiName (TableDesc->Pointer->Signature) ? TableDesc->Pointer->Signature : "????", *(UINT32 *) TableDesc->Pointer->Signature)); return_ACPI_STATUS (AE_BAD_SIGNATURE); } (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); /* Check if table is already registered */ for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) { if (!AcpiGbl_RootTableList.Tables[i].Pointer) { Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]); if (ACPI_FAILURE (Status) || !AcpiGbl_RootTableList.Tables[i].Pointer) { continue; } } /* * Check for a table match on the entire table length, * not just the header. */ if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length) { continue; } if (ACPI_MEMCMP (TableDesc->Pointer, AcpiGbl_RootTableList.Tables[i].Pointer, AcpiGbl_RootTableList.Tables[i].Length)) { continue; } /* * Note: the current mechanism does not unregister a table if it is * dynamically unloaded. The related namespace entries are deleted, * but the table remains in the root table list. * * The assumption here is that the number of different tables that * will be loaded is actually small, and there is minimal overhead * in just keeping the table in case it is needed again. * * If this assumption changes in the future (perhaps on large * machines with many table load/unload operations), tables will * need to be unregistered when they are unloaded, and slots in the * root table list should be reused when empty. */ /* * Table is already registered. * We can delete the table that was passed as a parameter. */ AcpiTbDeleteTable (TableDesc); *TableIndex = i; if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED) { /* Table is still loaded, this is an error */ Status = AE_ALREADY_EXISTS; goto Release; } else { /* Table was unloaded, allow it to be reloaded */ TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer; TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address; Status = AE_OK; goto PrintHeader; } } /* * ACPI Table Override: * Allow the host to override dynamically loaded tables. * NOTE: the table is fully mapped at this point, and the mapping will * be deleted by TbTableOverride if the table is actually overridden. */ (void) AcpiTbTableOverride (TableDesc->Pointer, TableDesc); /* Add the table to the global root table list */ Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer, TableDesc->Length, TableDesc->Flags, TableIndex); if (ACPI_FAILURE (Status)) { goto Release; } PrintHeader: AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer); Release: (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); return_ACPI_STATUS (Status); }
ACPI_STATUS AdParseTable ( ACPI_TABLE_HEADER *Table, ACPI_OWNER_ID *OwnerId, BOOLEAN LoadTable, BOOLEAN External) { ACPI_STATUS Status = AE_OK; ACPI_WALK_STATE *WalkState; UINT8 *AmlStart; UINT32 AmlLength; UINT32 TableIndex; if (!Table) { return (AE_NOT_EXIST); } /* Pass 1: Parse everything except control method bodies */ fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature); AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER); AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)); /* Create the root object */ AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp (); if (!AcpiGbl_ParseOpRoot) { return (AE_NO_MEMORY); } /* Create and initialize a new walk state */ WalkState = AcpiDsCreateWalkState (0, AcpiGbl_ParseOpRoot, NULL, NULL); if (!WalkState) { return (AE_NO_MEMORY); } Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot, NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); if (ACPI_FAILURE (Status)) { return (Status); } WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; Status = AcpiPsParseAml (WalkState); if (ACPI_FAILURE (Status)) { return (Status); } /* If LoadTable is FALSE, we are parsing the last loaded table */ TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1; /* Pass 2 */ if (LoadTable) { Status = AcpiTbStoreTable ((ACPI_PHYSICAL_ADDRESS) Table, Table, Table->Length, ACPI_TABLE_ORIGIN_ALLOCATED, &TableIndex); if (ACPI_FAILURE (Status)) { return (Status); } Status = AcpiTbAllocateOwnerId (TableIndex); if (ACPI_FAILURE (Status)) { return (Status); } if (OwnerId) { Status = AcpiTbGetOwnerId (TableIndex, OwnerId); if (ACPI_FAILURE (Status)) { return (Status); } } } fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature); Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL); if (ACPI_FAILURE (Status)) { return (Status); } /* No need to parse control methods of external table */ if (External) { return (AE_OK); } /* Pass 3: Parse control methods and link their parse trees into the main parse tree */ fprintf (stderr, "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n"); Status = AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot); fprintf (stderr, "\n"); /* Process Resource Templates */ AcpiDmFindResources (AcpiGbl_ParseOpRoot); fprintf (stderr, "Parsing completed\n"); return (AE_OK); }
ACPI_STATUS AdGetLocalTables ( char *Filename, BOOLEAN GetAllTables) { ACPI_STATUS Status; ACPI_TABLE_HEADER TableHeader; ACPI_TABLE_HEADER *NewTable; UINT32 NumTables; UINT32 PointerSize; UINT32 TableIndex; if (GetAllTables) { ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_RSDT); AcpiOsTableOverride (&TableHeader, &NewTable); if (!NewTable) { fprintf (stderr, "Could not obtain RSDT\n"); return (AE_NO_ACPI_TABLES); } else { AdWriteTable (NewTable, NewTable->Length, ACPI_SIG_RSDT, NewTable->OemTableId); } if (ACPI_COMPARE_NAME (NewTable->Signature, ACPI_SIG_RSDT)) { PointerSize = sizeof (UINT32); } else { PointerSize = sizeof (UINT64); } /* * Determine the number of tables pointed to by the RSDT/XSDT. * This is defined by the ACPI Specification to be the number of * pointers contained within the RSDT/XSDT. The size of the pointers * is architecture-dependent. */ NumTables = (NewTable->Length - sizeof (ACPI_TABLE_HEADER)) / PointerSize; AcpiOsPrintf ("There are %u tables defined in the %4.4s\n\n", NumTables, NewTable->Signature); /* Get the FADT */ ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_FADT); AcpiOsTableOverride (&TableHeader, &NewTable); if (NewTable) { AdWriteTable (NewTable, NewTable->Length, ACPI_SIG_FADT, NewTable->OemTableId); } AcpiOsPrintf ("\n"); /* Don't bother with FACS, it is usually all zeros */ } /* Always get the DSDT */ ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT); AcpiOsTableOverride (&TableHeader, &NewTable); if (NewTable) { AdWriteTable (NewTable, NewTable->Length, ACPI_SIG_DSDT, NewTable->OemTableId); /* Store DSDT in the Table Manager */ Status = AcpiTbStoreTable (0, NewTable, NewTable->Length, 0, &TableIndex); if (ACPI_FAILURE (Status)) { fprintf (stderr, "Could not store DSDT\n"); return (AE_NO_ACPI_TABLES); } } else { fprintf (stderr, "Could not obtain DSDT\n"); return (AE_NO_ACPI_TABLES); } #if 0 /* TBD: Future implementation */ AcpiOsPrintf ("\n"); /* Get all SSDTs */ ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_SSDT); do { NewTable = NULL; Status = AcpiOsTableOverride (&TableHeader, &NewTable); } while (NewTable); #endif return (AE_OK); }
/* We can delete the table that was passed as a parameter */ AcpiTbDeleteTable (TableDesc); /* Setup descriptor for the new table */ TableDesc->Address = ACPI_PTR_TO_PHYSADDR (OverrideTable); TableDesc->Pointer = OverrideTable; TableDesc->Length = OverrideTable->Length; TableDesc->Flags = ACPI_TABLE_ORIGIN_OVERRIDE; } /* Add the table to the global root table list */ Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer, TableDesc->Length, TableDesc->Flags, TableIndex); if (ACPI_FAILURE (Status)) { goto Release; } PrintHeader: AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer); Release: (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); return_ACPI_STATUS (Status); } /*******************************************************************************