void AcpiDbAddToHistory ( char *CommandLine) { UINT16 CmdLen; UINT16 BufferLen; /* Put command into the next available slot */ CmdLen = (UINT16) ACPI_STRLEN (CommandLine); if (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command != NULL) { BufferLen = (UINT16) ACPI_STRLEN ( AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command); if (CmdLen > BufferLen) { AcpiOsFree (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex]. Command); AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command = AcpiOsAllocate (CmdLen + 1); } } else { AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command = AcpiOsAllocate (CmdLen + 1); } ACPI_STRCPY (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command, CommandLine); AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].CmdNum = AcpiGbl_NextCmdNum; /* Adjust indexes */ if ((AcpiGbl_NumHistory == HISTORY_SIZE) && (AcpiGbl_NextHistoryIndex == AcpiGbl_LoHistory)) { AcpiGbl_LoHistory++; if (AcpiGbl_LoHistory >= HISTORY_SIZE) { AcpiGbl_LoHistory = 0; } } AcpiGbl_NextHistoryIndex++; if (AcpiGbl_NextHistoryIndex >= HISTORY_SIZE) { AcpiGbl_NextHistoryIndex = 0; } AcpiGbl_NextCmdNum++; if (AcpiGbl_NumHistory < HISTORY_SIZE) { AcpiGbl_NumHistory++; } }
ACPI_STATUS AcpiOsCreateCache ( const char *CacheName, UINT16 ObjectSize, UINT16 MaxDepth, ACPI_MEMORY_LIST **ReturnCache) { ACPI_MEMORY_LIST *Cache; ACPI_FUNCTION_ENTRY (); if (!CacheName || !ReturnCache || (ObjectSize < 16)) { return (AE_BAD_PARAMETER); } /* Create the cache object */ Cache = AcpiOsAllocate (sizeof (ACPI_MEMORY_LIST)); if (!Cache) { return (AE_NO_MEMORY); } /* Populate the cache object and return it */ memset (Cache, 0, sizeof (ACPI_MEMORY_LIST)); Cache->ListName = __UNCONST(CacheName); Cache->ObjectSize = ObjectSize; Cache->MaxDepth = MaxDepth; *ReturnCache = Cache; return (AE_OK); }
void * AcpiUtAllocate ( ACPI_SIZE Size, UINT32 Component, const char *Module, UINT32 Line) { void *Allocation; ACPI_FUNCTION_TRACE_U32 (UtAllocate, Size); /* Check for an inadvertent size of zero bytes */ if (!Size) { ACPI_WARNING ((Module, Line, "Attempt to allocate zero bytes, allocating 1 byte")); Size = 1; } Allocation = AcpiOsAllocate (Size); if (!Allocation) { /* Report allocation error */ ACPI_WARNING ((Module, Line, "Could not allocate size %u", (UINT32) Size)); return_PTR (NULL); } return_PTR (Allocation); }
static void acpi_res_set_init(device_t dev, void *arg, void **context) { struct acpi_res_context *cp; if ((cp = AcpiOsAllocate(sizeof(*cp))) != NULL) { bzero(cp, sizeof(*cp)); cp->ar_parent = arg; *context = cp; } }
void * AcpiUtAllocateAndTrack ( ACPI_SIZE Size, UINT32 Component, const char *Module, UINT32 Line) { ACPI_DEBUG_MEM_BLOCK *Allocation; ACPI_STATUS Status; /* Check for an inadvertent size of zero bytes */ if (!Size) { ACPI_WARNING ((Module, Line, "Attempt to allocate zero bytes, allocating 1 byte")); Size = 1; } Allocation = AcpiOsAllocate (Size + sizeof (ACPI_DEBUG_MEM_HEADER)); if (!Allocation) { /* Report allocation error */ ACPI_WARNING ((Module, Line, "Could not allocate size %u", (UINT32) Size)); return (NULL); } Status = AcpiUtTrackAllocation ( Allocation, Size, ACPI_MEM_MALLOC, Component, Module, Line); if (ACPI_FAILURE (Status)) { AcpiOsFree (Allocation); return (NULL); } AcpiGbl_GlobalList->TotalAllocated++; AcpiGbl_GlobalList->TotalSize += (UINT32) Size; AcpiGbl_GlobalList->CurrentTotalSize += (UINT32) Size; if (AcpiGbl_GlobalList->CurrentTotalSize > AcpiGbl_GlobalList->MaxOccupied) { AcpiGbl_GlobalList->MaxOccupied = AcpiGbl_GlobalList->CurrentTotalSize; } return ((void *) &Allocation->UserSpace); }
void * AcpiUtAllocate ( UINT32 Size, UINT32 Component, NATIVE_CHAR *Module, UINT32 Line) { ACPI_DEBUG_MEM_BLOCK *Address; ACPI_STATUS Status; FUNCTION_TRACE_U32 ("UtAllocate", Size); /* Check for an inadvertent size of zero bytes */ if (!Size) { _REPORT_ERROR (Module, Line, Component, ("UtAllocate: Attempt to allocate zero bytes\n")); Size = 1; } Address = AcpiOsAllocate (Size + sizeof (ACPI_DEBUG_MEM_BLOCK)); if (!Address) { /* Report allocation error */ _REPORT_ERROR (Module, Line, Component, ("UtAllocate: Could not allocate size %X\n", Size)); return_PTR (NULL); } Status = AcpiUtAddElementToAllocList (ACPI_MEM_LIST_GLOBAL, Address, Size, MEM_MALLOC, Component, Module, Line); if (ACPI_FAILURE (Status)) { AcpiOsFree (Address); return_PTR (NULL); } AcpiGbl_MemoryLists[ACPI_MEM_LIST_GLOBAL].TotalAllocated++; AcpiGbl_MemoryLists[ACPI_MEM_LIST_GLOBAL].CurrentTotalSize += Size; ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n", Address, Size)); return_PTR ((void *) &Address->UserSpace); }
void * AcpiOsAllocateZeroed ( ACPI_SIZE Size) { void *Mem; Mem = AcpiOsAllocate (Size); if (Mem) { ACPI_MEMSET (Mem, 0, Size); } return (Mem); }
static char * FlStrdup ( char *String) { char *NewString; NewString = AcpiOsAllocate (strlen (String) + 1); if (!NewString) { return (NULL); } strcpy (NewString, String); return (NewString); }
ACPI_STATUS AcpiOsCreateSemaphore ( UINT32 MaxUnits, UINT32 InitialUnits, ACPI_HANDLE *OutHandle) { sem_t *Sem; if (!OutHandle) { return (AE_BAD_PARAMETER); } #ifdef __APPLE__ { static int SemaphoreCount = 0; char SemaphoreName[32]; snprintf (SemaphoreName, sizeof (SemaphoreName), "acpi_sem_%d", SemaphoreCount++); printf ("%s\n", SemaphoreName); Sem = sem_open (SemaphoreName, O_EXCL|O_CREAT, 0755, InitialUnits); if (!Sem) { return (AE_NO_MEMORY); } sem_unlink (SemaphoreName); /* This just deletes the name */ } #else Sem = AcpiOsAllocate (sizeof (sem_t)); if (!Sem) { return (AE_NO_MEMORY); } if (sem_init (Sem, 0, InitialUnits) == -1) { AcpiOsFree (Sem); return (AE_BAD_PARAMETER); } #endif *OutHandle = (ACPI_HANDLE) Sem; return (AE_OK); }
ACPI_STATUS AcpiOsCreateSemaphore ( UINT32 MaxUnits, UINT32 InitialUnits, ACPI_HANDLE *OutHandle) { #if 0 sem_t *Sem; if (!OutHandle) { return (AE_BAD_PARAMETER); } #ifdef __APPLE__ { char *SemaphoreName = tmpnam (NULL); Sem = sem_open (SemaphoreName, O_EXCL|O_CREAT, 0755, InitialUnits); if (!Sem) { return (AE_NO_MEMORY); } sem_unlink (SemaphoreName); /* This just deletes the name */ } #else Sem = AcpiOsAllocate (sizeof (sem_t)); if (!Sem) { return (AE_NO_MEMORY); } if (sem_init (Sem, 0, InitialUnits) == -1) { AcpiOsFree (Sem); return (AE_BAD_PARAMETER); } #endif *OutHandle = (ACPI_HANDLE) Sem; #endif *OutHandle = (ACPI_HANDLE) 1; return (AE_OK); }
void * AcpiOsAllocateZeroed ( ACPI_SIZE Size) { void *Allocation; ACPI_FUNCTION_ENTRY (); Allocation = AcpiOsAllocate (Size); if (Allocation) { /* Clear the memory block */ ACPI_MEMSET (Allocation, 0, Size); } return (Allocation); }
ACPI_STATUS AcpiUtCreateList ( char *ListName, UINT16 ObjectSize, ACPI_MEMORY_LIST **ReturnCache) { ACPI_MEMORY_LIST *Cache; Cache = AcpiOsAllocate (sizeof (ACPI_MEMORY_LIST)); if (!Cache) { return (AE_NO_MEMORY); } ACPI_MEMSET (Cache, 0, sizeof (ACPI_MEMORY_LIST)); Cache->ListName = ListName; Cache->ObjectSize = ObjectSize; *ReturnCache = Cache; return (AE_OK); }
int ACPI_SYSTEM_XFACE main ( int argc, char **argv) { int j; ACPI_STATUS Status; UINT32 InitFlags; ACPI_TABLE_HEADER *Table = NULL; UINT32 TableCount; AE_TABLE_DESC *TableDesc; char **WildcardList; char *Filename; char *Directory; char *FullPathname; #ifdef _DEBUG _CrtSetDbgFlag (_CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)); #endif printf (ACPI_COMMON_SIGNON ("AML Execution/Debug Utility")); if (argc < 2) { usage (); return (0); } signal (SIGINT, AeCtrlCHandler); /* Init globals */ AcpiDbgLevel = ACPI_NORMAL_DEFAULT; AcpiDbgLayer = 0xFFFFFFFF; /* Init ACPI and start debugger thread */ Status = AcpiInitializeSubsystem (); AE_CHECK_OK (AcpiInitializeSubsystem, Status); /* Get the command line options */ while ((j = AcpiGetopt (argc, argv, AE_SUPPORTED_OPTIONS)) != EOF) switch(j) { case 'b': if (strlen (AcpiGbl_Optarg) > 127) { printf ("**** The length of command line (%u) exceeded maximum (127)\n", (UINT32) strlen (AcpiGbl_Optarg)); return (-1); } AcpiGbl_BatchMode = 1; strcpy (BatchBuffer, AcpiGbl_Optarg); break; case 'd': switch (AcpiGbl_Optarg[0]) { case 'a': AcpiGbl_IgnoreErrors = TRUE; break; case 'i': AcpiGbl_DbOpt_ini_methods = FALSE; break; case 'o': AcpiGbl_DbOpt_NoRegionSupport = TRUE; break; case 'r': AcpiGbl_DisableAutoRepair = TRUE; break; case 't': #ifdef ACPI_DBG_TRACK_ALLOCATIONS AcpiGbl_DisableMemTracking = TRUE; #endif break; default: printf ("Unknown option: -d%s\n", AcpiGbl_Optarg); return (-1); } break; case 'e': switch (AcpiGbl_Optarg[0]) { case 'f': #ifdef ACPI_DBG_TRACK_ALLOCATIONS AcpiGbl_DisplayFinalMemStats = TRUE; #endif break; case 'm': AcpiGbl_AllMethodsSerialized = TRUE; printf ("Enabling AML Interpreter serialized mode\n"); break; case 's': AcpiGbl_EnableInterpreterSlack = TRUE; printf ("Enabling AML Interpreter slack mode\n"); break; case 't': AcpiGbl_DebugTimeout = TRUE; break; default: printf ("Unknown option: -e%s\n", AcpiGbl_Optarg); return (-1); } break; case 'f': AcpiGbl_RegionFillValue = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); break; case 'g': AcpiGbl_DbOpt_tables = TRUE; AcpiGbl_DbFilename = NULL; break; case 'm': AcpiGbl_BatchMode = 2; switch (AcpiGbl_Optarg[0]) { case '^': strcpy (BatchBuffer, "MAIN"); break; default: strcpy (BatchBuffer, AcpiGbl_Optarg); break; } break; case 'o': AcpiGbl_DbOpt_disasm = TRUE; AcpiGbl_DbOpt_stats = TRUE; break; case 'v': AcpiDbgLevel |= ACPI_LV_INIT_NAMES; break; case 'x': AcpiDbgLevel = strtoul (AcpiGbl_Optarg, NULL, 0); AcpiGbl_DbConsoleDebugLevel = AcpiDbgLevel; printf ("Debug Level: 0x%8.8X\n", AcpiDbgLevel); break; case '?': case 'h': default: usage(); return (-1); } InitFlags = (ACPI_NO_HANDLER_INIT | ACPI_NO_ACPI_ENABLE); if (!AcpiGbl_DbOpt_ini_methods) { InitFlags |= (ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT); } /* The remaining arguments are filenames for ACPI tables */ if (argv[AcpiGbl_Optind]) { AcpiGbl_DbOpt_tables = TRUE; TableCount = 0; /* Get each of the ACPI table files on the command line */ while (argv[AcpiGbl_Optind]) { /* Split incoming path into a directory/filename combo */ Status = FlSplitInputPathname (argv[AcpiGbl_Optind], &Directory, &Filename); if (ACPI_FAILURE (Status)) { return (Status); } /* Expand wildcards (Windows only) */ WildcardList = AsDoWildcard (Directory, Filename); if (!WildcardList) { return (-1); } while (*WildcardList) { FullPathname = AcpiOsAllocate ( strlen (Directory) + strlen (*WildcardList) + 1); /* Construct a full path to the file */ strcpy (FullPathname, Directory); strcat (FullPathname, *WildcardList); /* Get one table */ Status = AcpiDbReadTableFromFile (FullPathname, &Table); if (ACPI_FAILURE (Status)) { printf ("**** Could not get input table %s, %s\n", FullPathname, AcpiFormatException (Status)); goto enterloop; } AcpiOsFree (FullPathname); AcpiOsFree (*WildcardList); *WildcardList = NULL; WildcardList++; /* * Ignore an FACS or RSDT, we can't use them. */ if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS) || ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDT)) { AcpiOsFree (Table); continue; } /* Allocate and link a table descriptor */ TableDesc = AcpiOsAllocate (sizeof (AE_TABLE_DESC)); TableDesc->Table = Table; TableDesc->Next = AeTableListHead; AeTableListHead = TableDesc; TableCount++; } AcpiGbl_Optind++; } /* Build a local RSDT with all tables and let ACPICA process the RSDT */ Status = AeBuildLocalTables (TableCount, AeTableListHead); if (ACPI_FAILURE (Status)) { return (-1); } Status = AeInstallTables (); if (ACPI_FAILURE (Status)) { printf ("**** Could not load ACPI tables, %s\n", AcpiFormatException (Status)); goto enterloop; } /* * Install most of the handlers. * Override some default region handlers, especially SystemMemory */ Status = AeInstallEarlyHandlers (); if (ACPI_FAILURE (Status)) { goto enterloop; } /* * TBD: Need a way to call this after the "LOAD" command */ Status = AcpiEnableSubsystem (InitFlags); if (ACPI_FAILURE (Status)) { printf ("**** Could not EnableSubsystem, %s\n", AcpiFormatException (Status)); goto enterloop; } Status = AcpiInitializeObjects (InitFlags); if (ACPI_FAILURE (Status)) { printf ("**** Could not InitializeObjects, %s\n", AcpiFormatException (Status)); goto enterloop; } /* * Install handlers for "device driver" space IDs (EC,SMBus, etc.) * and fixed event handlers */ AeInstallLateHandlers (); AeMiscellaneousTests (); } enterloop: if (AcpiGbl_BatchMode == 1) { AcpiDbRunBatchMode (); } else if (AcpiGbl_BatchMode == 2) { AcpiDbExecute (BatchBuffer, NULL, NULL, EX_NO_SINGLE_STEP); } else { /* Enter the debugger command loop */ AcpiDbUserCommands (ACPI_DEBUGGER_COMMAND_PROMPT, NULL); } return (0); }
ACPI_STATUS AcpiUtInitializeBuffer ( ACPI_BUFFER *Buffer, ACPI_SIZE RequiredLength) { ACPI_SIZE InputBufferLength; /* Parameter validation */ if (!Buffer || !RequiredLength) { return (AE_BAD_PARAMETER); } /* * Buffer->Length is used as both an input and output parameter. Get the * input actual length and set the output required buffer length. */ InputBufferLength = Buffer->Length; Buffer->Length = RequiredLength; /* * The input buffer length contains the actual buffer length, or the type * of buffer to be allocated by this routine. */ switch (InputBufferLength) { case ACPI_NO_BUFFER: /* Return the exception (and the required buffer length) */ return (AE_BUFFER_OVERFLOW); case ACPI_ALLOCATE_BUFFER: /* Allocate a new buffer */ Buffer->Pointer = AcpiOsAllocate (RequiredLength); break; case ACPI_ALLOCATE_LOCAL_BUFFER: /* Allocate a new buffer with local interface to allow tracking */ Buffer->Pointer = ACPI_ALLOCATE (RequiredLength); break; default: /* Existing buffer: Validate the size of the buffer */ if (InputBufferLength < RequiredLength) { return (AE_BUFFER_OVERFLOW); } break; } /* Validate allocation from above or input buffer pointer */ if (!Buffer->Pointer) { return (AE_NO_MEMORY); } /* Have a valid buffer, clear it */ ACPI_MEMSET (Buffer->Pointer, 0, RequiredLength); return (AE_OK); }
void AbComputeChecksum ( char *FilePath) { UINT32 Actual; ACPI_TABLE_HEADER *Table; UINT8 Checksum; FILE *File; File = fopen (FilePath, "rb"); if (!File) { printf ("Could not open file %s\n", FilePath); return; } Actual = fread (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File); if (Actual < sizeof (ACPI_TABLE_HEADER)) { printf ("File %s does not contain a valid ACPI table header\n", FilePath); goto Exit1; } if (!AbValidateHeader (&Header1)) { goto Exit1; } if (!Gbl_TerseMode) { AbPrintHeaderInfo (&Header1); } /* Allocate a buffer to hold the entire table */ Table = AcpiOsAllocate (Header1.Length); if (!Table) { printf ("Could not allocate buffer for table\n"); goto Exit1; } /* Read the entire table, including header */ fseek (File, 0, SEEK_SET); Actual = fread (Table, 1, Header1.Length, File); if (Actual != Header1.Length) { printf ("Could not read table, length %u\n", Header1.Length); goto Exit2; } /* Compute the checksum for the table */ Table->Checksum = 0; Checksum = (UINT8) (0 - AcpiTbSumTable (Table, Table->Length)); printf ("Computed checksum: 0x%X\n\n", Checksum); if (Header1.Checksum == Checksum) { printf ("Checksum OK in AML file, not updating\n"); goto Exit2; } /* Open the target file for writing, to update checksum */ fclose (File); File = fopen (FilePath, "r+b"); if (!File) { printf ("Could not open file %s for writing\n", FilePath); goto Exit2; } /* Set the checksum, write the new header */ Header1.Checksum = Checksum; Actual = fwrite (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File); if (Actual != sizeof (ACPI_TABLE_HEADER)) { printf ("Could not write updated table header\n"); goto Exit2; } printf ("Wrote new checksum\n"); Exit2: AcpiOsFree (Table); Exit1: if (File) { fclose (File); } return; }
static ACPI_STATUS AcpiDbReadTable ( FILE *fp, ACPI_TABLE_HEADER **Table, UINT32 *TableLength) { ACPI_TABLE_HEADER TableHeader; UINT32 Actual; ACPI_STATUS Status; UINT32 FileSize; BOOLEAN StandardHeader = TRUE; /* Get the file size */ fseek (fp, 0, SEEK_END); FileSize = (UINT32) ftell (fp); fseek (fp, 0, SEEK_SET); if (FileSize < 4) { return (AE_BAD_HEADER); } /* Read the signature */ if (fread (&TableHeader, 1, 4, fp) != 4) { AcpiOsPrintf ("Could not read the table signature\n"); return (AE_BAD_HEADER); } fseek (fp, 0, SEEK_SET); /* The RSDT, FACS and S3PT tables do not have standard ACPI headers */ if (ACPI_COMPARE_NAME (TableHeader.Signature, "RSD ") || ACPI_COMPARE_NAME (TableHeader.Signature, "FACS") || ACPI_COMPARE_NAME (TableHeader.Signature, "S3PT")) { *TableLength = FileSize; StandardHeader = FALSE; } else { /* Read the table header */ if (fread (&TableHeader, 1, sizeof (TableHeader), fp) != sizeof (ACPI_TABLE_HEADER)) { AcpiOsPrintf ("Could not read the table header\n"); return (AE_BAD_HEADER); } #if 0 /* Validate the table header/length */ Status = AcpiTbValidateTableHeader (&TableHeader); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Table header is invalid!\n"); return (Status); } #endif /* File size must be at least as long as the Header-specified length */ if (TableHeader.Length > FileSize) { AcpiOsPrintf ( "TableHeader length [0x%X] greater than the input file size [0x%X]\n", TableHeader.Length, FileSize); return (AE_BAD_HEADER); } #ifdef ACPI_OBSOLETE_CODE /* We only support a limited number of table types */ if (ACPI_STRNCMP ((char *) TableHeader.Signature, DSDT_SIG, 4) && ACPI_STRNCMP ((char *) TableHeader.Signature, PSDT_SIG, 4) && ACPI_STRNCMP ((char *) TableHeader.Signature, SSDT_SIG, 4)) { AcpiOsPrintf ("Table signature [%4.4s] is invalid or not supported\n", (char *) TableHeader.Signature); ACPI_DUMP_BUFFER (&TableHeader, sizeof (ACPI_TABLE_HEADER)); return (AE_ERROR); } #endif *TableLength = TableHeader.Length; } /* Allocate a buffer for the table */ *Table = AcpiOsAllocate ((size_t) FileSize); if (!*Table) { AcpiOsPrintf ( "Could not allocate memory for ACPI table %4.4s (size=0x%X)\n", TableHeader.Signature, *TableLength); return (AE_NO_MEMORY); } /* Get the rest of the table */ fseek (fp, 0, SEEK_SET); Actual = fread (*Table, 1, (size_t) FileSize, fp); if (Actual == FileSize) { if (StandardHeader) { /* Now validate the checksum */ Status = AcpiTbVerifyChecksum ((void *) *Table, ACPI_CAST_PTR (ACPI_TABLE_HEADER, *Table)->Length); if (Status == AE_BAD_CHECKSUM) { Status = AcpiDbCheckTextModeCorruption ((UINT8 *) *Table, FileSize, (*Table)->Length); return (Status); } } return (AE_OK); } if (Actual > 0) { AcpiOsPrintf ("Warning - reading table, asked for %X got %X\n", FileSize, Actual); return (AE_OK); } AcpiOsPrintf ("Error - could not read the table file\n"); AcpiOsFree (*Table); *Table = NULL; *TableLength = 0; return (AE_ERROR); }
static ACPI_STATUS AcGetOneTableFromFile ( char *Filename, FILE *File, UINT8 GetOnlyAmlTables, ACPI_TABLE_HEADER **ReturnTable) { ACPI_STATUS Status = AE_OK; ACPI_TABLE_HEADER TableHeader; ACPI_TABLE_HEADER *Table; INT32 Count; long TableOffset; *ReturnTable = NULL; /* Get the table header to examine signature and length */ TableOffset = ftell (File); Count = fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), File); if (Count != sizeof (ACPI_TABLE_HEADER)) { return (AE_CTRL_TERMINATE); } /* Validate the table signature/header (limited ASCII chars) */ Status = AcValidateTableHeader (File, TableOffset); if (ACPI_FAILURE (Status)) { return (Status); } if (GetOnlyAmlTables) { /* * Table must be an AML table (DSDT/SSDT). * Used for iASL -e option only. */ if (!AcpiUtIsAmlTable (&TableHeader)) { fprintf (stderr, " %s: Table [%4.4s] is not an AML table - ignoring\n", Filename, TableHeader.Signature); return (AE_TYPE); } } /* Allocate a buffer for the entire table */ Table = AcpiOsAllocate ((ACPI_SIZE) TableHeader.Length); if (!Table) { return (AE_NO_MEMORY); } /* Read the entire ACPI table, including header */ fseek (File, TableOffset, SEEK_SET); Count = fread (Table, 1, TableHeader.Length, File); if (Count != (INT32) TableHeader.Length) { Status = AE_ERROR; goto ErrorExit; } /* Validate the checksum (just issue a warning) */ Status = AcpiTbVerifyChecksum (Table, TableHeader.Length); if (ACPI_FAILURE (Status)) { Status = AcCheckTextModeCorruption (Table); if (ACPI_FAILURE (Status)) { goto ErrorExit; } } *ReturnTable = Table; return (AE_OK); ErrorExit: AcpiOsFree (Table); return (Status); }
ACPI_STATUS AcGetAllTablesFromFile ( char *Filename, UINT8 GetOnlyAmlTables, ACPI_NEW_TABLE_DESC **ReturnListHead) { ACPI_NEW_TABLE_DESC *ListHead = NULL; ACPI_NEW_TABLE_DESC *ListTail = NULL; ACPI_NEW_TABLE_DESC *TableDesc; FILE *File; ACPI_TABLE_HEADER *Table = NULL; UINT32 FileSize; ACPI_STATUS Status = AE_OK; File = fopen (Filename, "rb"); if (!File) { fprintf (stderr, "Could not open input file: %s\n", Filename); if (errno == ENOENT) { return (AE_NOT_EXIST); } return (AE_ERROR); } /* Get the file size */ FileSize = CmGetFileSize (File); if (FileSize == ACPI_UINT32_MAX) { Status = AE_ERROR; goto Exit; } fprintf (stderr, "Input file %s, Length 0x%X (%u) bytes\n", Filename, FileSize, FileSize); /* We must have at least one ACPI table header */ if (FileSize < sizeof (ACPI_TABLE_HEADER)) { Status = AE_BAD_HEADER; goto Exit; } /* Check for an non-binary file */ if (!AcIsFileBinary (File)) { fprintf (stderr, " %s: File does not appear to contain a valid AML table\n", Filename); Status = AE_TYPE; goto Exit; } /* Read all tables within the file */ while (ACPI_SUCCESS (Status)) { /* Get one entire ACPI table */ Status = AcGetOneTableFromFile ( Filename, File, GetOnlyAmlTables, &Table); if (Status == AE_CTRL_TERMINATE) { Status = AE_OK; break; } else if (Status == AE_TYPE) { Status = AE_OK; goto Exit; } else if (ACPI_FAILURE (Status)) { goto Exit; } /* Print table header for iASL/disassembler only */ #ifdef ACPI_ASL_COMPILER AcpiTbPrintTableHeader (0, Table); #endif /* Allocate and link a table descriptor */ TableDesc = AcpiOsAllocate (sizeof (ACPI_NEW_TABLE_DESC)); if (!TableDesc) { AcpiOsFree (Table); Status = AE_NO_MEMORY; goto Exit; } TableDesc->Table = Table; TableDesc->Next = NULL; /* Link at the end of the local table list */ if (!ListHead) { ListHead = TableDesc; ListTail = TableDesc; } else { ListTail->Next = TableDesc; ListTail = TableDesc; } } /* Add the local table list to the end of the global list */ if (*ReturnListHead) { ListTail = *ReturnListHead; while (ListTail->Next) { ListTail = ListTail->Next; } ListTail->Next = ListHead; } else { *ReturnListHead = ListHead; } Exit: fclose(File); return (Status); }
int ACPI_SYSTEM_XFACE main ( int argc, char **argv) { ACPI_STATUS Status; UINT32 InitFlags; ACPI_TABLE_HEADER *Table = NULL; UINT32 TableCount; AE_TABLE_DESC *TableDesc; ACPI_DEBUG_INITIALIZE (); /* For debug version only */ signal (SIGINT, AeCtrlCHandler); /* Init debug globals */ AcpiDbgLevel = ACPI_NORMAL_DEFAULT; AcpiDbgLayer = 0xFFFFFFFF; /* Init ACPICA and start debugger thread */ Status = AcpiInitializeSubsystem (); AE_CHECK_OK (AcpiInitializeSubsystem, Status); if (ACPI_FAILURE (Status)) { goto ErrorExit; } printf (ACPI_COMMON_SIGNON (ACPIEXEC_NAME)); if (argc < 2) { usage (); (void) AcpiOsTerminate (); return (0); } /* Get the command line options */ if (AeDoOptions (argc, argv)) { goto ErrorExit; } /* The remaining arguments are filenames for ACPI tables */ if (!argv[AcpiGbl_Optind]) { goto EnterDebugger; } AcpiGbl_DbOpt_tables = TRUE; AcpiGbl_CstyleDisassembly = FALSE; /* Not supported for AcpiExec */ TableCount = 0; /* Get each of the ACPI table files on the command line */ while (argv[AcpiGbl_Optind]) { /* Get one entire table */ Status = AcpiUtReadTableFromFile (argv[AcpiGbl_Optind], &Table); if (ACPI_FAILURE (Status)) { printf ("**** Could not get table from file %s, %s\n", argv[AcpiGbl_Optind], AcpiFormatException (Status)); goto ErrorExit; } /* Ignore non-AML tables, we can't use them. Except for an FADT */ if (!ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FADT) && !AcpiUtIsAmlTable (Table)) { ACPI_INFO ((AE_INFO, "Table [%4.4s] is not an AML table, ignoring", Table->Signature)); AcpiOsFree (Table); } else { /* Allocate and link a table descriptor */ TableDesc = AcpiOsAllocate (sizeof (AE_TABLE_DESC)); TableDesc->Table = Table; TableDesc->Next = AeTableListHead; AeTableListHead = TableDesc; TableCount++; } AcpiGbl_Optind++; } printf ("\n"); /* Build a local RSDT with all tables and let ACPICA process the RSDT */ Status = AeBuildLocalTables (TableCount, AeTableListHead); if (ACPI_FAILURE (Status)) { goto ErrorExit; } Status = AeInstallTables (); if (ACPI_FAILURE (Status)) { printf ("**** Could not load ACPI tables, %s\n", AcpiFormatException (Status)); goto EnterDebugger; } /* * Install most of the handlers. * Override some default region handlers, especially SystemMemory */ Status = AeInstallEarlyHandlers (); if (ACPI_FAILURE (Status)) { goto EnterDebugger; } /* Setup initialization flags for ACPICA */ InitFlags = (ACPI_NO_HANDLER_INIT | ACPI_NO_ACPI_ENABLE); if (!AcpiGbl_DbOpt_ini_methods) { InitFlags |= (ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT); } /* * Main initialization for ACPICA subsystem * TBD: Need a way to call this after the ACPI table "LOAD" command */ Status = AcpiEnableSubsystem (InitFlags); if (ACPI_FAILURE (Status)) { printf ("**** Could not EnableSubsystem, %s\n", AcpiFormatException (Status)); goto EnterDebugger; } /* * Install handlers for "device driver" space IDs (EC,SMBus, etc.) * and fixed event handlers */ AeInstallLateHandlers (); /* Finish the ACPICA initialization */ Status = AcpiInitializeObjects (InitFlags); if (ACPI_FAILURE (Status)) { printf ("**** Could not InitializeObjects, %s\n", AcpiFormatException (Status)); goto EnterDebugger; } AeMiscellaneousTests (); EnterDebugger: /* Exit if error above and we are in one of the batch modes */ if (ACPI_FAILURE (Status) && (AcpiGbl_ExecutionMode > 0)) { goto ErrorExit; } /* Run a batch command or enter the command loop */ switch (AcpiGbl_ExecutionMode) { default: case AE_MODE_COMMAND_LOOP: AcpiDbUserCommands (ACPI_DEBUGGER_COMMAND_PROMPT, NULL); break; case AE_MODE_BATCH_MULTIPLE: AcpiDbRunBatchMode (); break; case AE_MODE_BATCH_SINGLE: AcpiDbExecute (BatchBuffer, NULL, NULL, EX_NO_SINGLE_STEP); Status = AcpiTerminate (); break; } return (0); ErrorExit: (void) AcpiOsTerminate (); return (-1); }
static ACPI_STATUS AcpiUtReadTable ( FILE *fp, ACPI_TABLE_HEADER **Table, UINT32 *TableLength) { ACPI_TABLE_HEADER TableHeader; UINT32 Actual; ACPI_STATUS Status; UINT32 FileSize; BOOLEAN StandardHeader = TRUE; INT32 Count; /* Get the file size */ FileSize = CmGetFileSize (fp); if (FileSize == ACPI_UINT32_MAX) { return (AE_ERROR); } if (FileSize < 4) { return (AE_BAD_HEADER); } /* Read the signature */ fseek (fp, 0, SEEK_SET); Count = fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), fp); if (Count != sizeof (ACPI_TABLE_HEADER)) { AcpiOsPrintf ("Could not read the table header\n"); return (AE_BAD_HEADER); } /* The RSDP table does not have standard ACPI header */ if (ACPI_VALIDATE_RSDP_SIG (TableHeader.Signature)) { *TableLength = FileSize; StandardHeader = FALSE; } else { #if 0 /* Validate the table header/length */ Status = AcpiTbValidateTableHeader (&TableHeader); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Table header is invalid!\n"); return (Status); } #endif /* File size must be at least as long as the Header-specified length */ if (TableHeader.Length > FileSize) { AcpiOsPrintf ( "TableHeader length [0x%X] greater than the input file size [0x%X]\n", TableHeader.Length, FileSize); #ifdef ACPI_ASL_COMPILER AcpiOsPrintf ("File is corrupt or is ASCII text -- " "it must be a binary file\n"); #endif return (AE_BAD_HEADER); } #ifdef ACPI_OBSOLETE_CODE /* We only support a limited number of table types */ if (!ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_DSDT) && !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_PSDT) && !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_SSDT)) { AcpiOsPrintf ("Table signature [%4.4s] is invalid or not supported\n", (char *) TableHeader.Signature); ACPI_DUMP_BUFFER (&TableHeader, sizeof (ACPI_TABLE_HEADER)); return (AE_ERROR); } #endif *TableLength = TableHeader.Length; } /* Allocate a buffer for the table */ *Table = AcpiOsAllocate ((size_t) FileSize); if (!*Table) { AcpiOsPrintf ( "Could not allocate memory for ACPI table %4.4s (size=0x%X)\n", TableHeader.Signature, *TableLength); return (AE_NO_MEMORY); } /* Get the rest of the table */ fseek (fp, 0, SEEK_SET); Actual = fread (*Table, 1, (size_t) FileSize, fp); if (Actual == FileSize) { if (StandardHeader) { /* Now validate the checksum */ Status = AcpiTbVerifyChecksum ((void *) *Table, ACPI_CAST_PTR (ACPI_TABLE_HEADER, *Table)->Length); if (Status == AE_BAD_CHECKSUM) { Status = AcpiUtCheckTextModeCorruption ((UINT8 *) *Table, FileSize, (*Table)->Length); return (Status); } } return (AE_OK); } if (Actual > 0) { AcpiOsPrintf ("Warning - reading table, asked for %X got %X\n", FileSize, Actual); return (AE_OK); } AcpiOsPrintf ("Error - could not read the table file\n"); AcpiOsFree (*Table); *Table = NULL; *TableLength = 0; return (AE_ERROR); }
ACPI_STATUS AcpiUtInitializeBuffer ( ACPI_BUFFER *Buffer, ACPI_SIZE RequiredLength) { ACPI_STATUS Status = AE_OK; switch (Buffer->Length) { case ACPI_NO_BUFFER: /* Set the exception and returned the required length */ Status = AE_BUFFER_OVERFLOW; break; case ACPI_ALLOCATE_BUFFER: /* Allocate a new buffer */ Buffer->Pointer = AcpiOsAllocate (RequiredLength); if (!Buffer->Pointer) { return (AE_NO_MEMORY); } /* Clear the buffer */ ACPI_MEMSET (Buffer->Pointer, 0, RequiredLength); break; case ACPI_ALLOCATE_LOCAL_BUFFER: /* Allocate a new buffer with local interface to allow tracking */ Buffer->Pointer = ACPI_ALLOCATE_ZEROED (RequiredLength); if (!Buffer->Pointer) { return (AE_NO_MEMORY); } break; default: /* Existing buffer: Validate the size of the buffer */ if (Buffer->Length < RequiredLength) { Status = AE_BUFFER_OVERFLOW; break; } /* Clear the buffer */ ACPI_MEMSET (Buffer->Pointer, 0, RequiredLength); break; } Buffer->Length = RequiredLength; return (Status); }
ACPI_STATUS AcpiDbInitialize ( void) { ACPI_STATUS Status; /* Init globals */ AcpiGbl_DbBuffer = NULL; AcpiGbl_DbFilename = NULL; AcpiGbl_DbOutputToFile = FALSE; AcpiGbl_DbDebugLevel = ACPI_LV_VERBOSITY2; AcpiGbl_DbConsoleDebugLevel = ACPI_NORMAL_DEFAULT | ACPI_LV_TABLES; AcpiGbl_DbOutputFlags = ACPI_DB_CONSOLE_OUTPUT; AcpiGbl_DbOpt_tables = FALSE; AcpiGbl_DbOpt_stats = FALSE; #ifdef ACPI_DISASSEMBLER AcpiGbl_DbOpt_disasm = FALSE; AcpiGbl_DbOpt_verbose = TRUE; #endif AcpiGbl_DbOpt_ini_methods = TRUE; AcpiGbl_DbBuffer = AcpiOsAllocate (ACPI_DEBUG_BUFFER_SIZE); if (!AcpiGbl_DbBuffer) { return (AE_NO_MEMORY); } ACPI_MEMSET (AcpiGbl_DbBuffer, 0, ACPI_DEBUG_BUFFER_SIZE); /* Initial scope is the root */ AcpiGbl_DbScopeBuf [0] = '\\'; AcpiGbl_DbScopeBuf [1] = 0; AcpiGbl_DbScopeNode = AcpiGbl_RootNode; /* * If configured for multi-thread support, the debug executor runs in * a separate thread so that the front end can be in another address * space, environment, or even another machine. */ if (AcpiGbl_DebuggerConfiguration & DEBUGGER_MULTI_THREADED) { /* These were created with one unit, grab it */ Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_COMPLETE); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not get debugger mutex\n"); return (Status); } Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_READY); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not get debugger mutex\n"); return (Status); } /* Create the debug execution thread to execute commands */ Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbExecuteThread, NULL); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not start debugger thread\n"); return (Status); } } #ifdef ACPI_DISASSEMBLER if (!AcpiGbl_DbOpt_verbose) { AcpiGbl_DbOpt_disasm = TRUE; AcpiGbl_DbOpt_stats = FALSE; } #endif return (AE_OK); }
ACPI_STATUS AeRegionHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, UINT64 *Value, void *HandlerContext, void *RegionContext) { ACPI_OPERAND_OBJECT *RegionObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, RegionContext); UINT8 *Buffer = ACPI_CAST_PTR (UINT8, Value); ACPI_PHYSICAL_ADDRESS BaseAddress; ACPI_SIZE Length; BOOLEAN BufferExists; AE_REGION *RegionElement; void *BufferValue; ACPI_STATUS Status; UINT32 ByteWidth; UINT32 i; UINT8 SpaceId; ACPI_FUNCTION_NAME (AeRegionHandler); /* * If the object is not a region, simply return */ if (RegionObject->Region.Type != ACPI_TYPE_REGION) { return AE_OK; } /* * Region support can be disabled with the -r option. * We use this to support dynamically loaded tables where we pass a valid * address to the AML. */ if (AcpiGbl_DbOpt_NoRegionSupport) { BufferValue = ACPI_TO_POINTER (Address); ByteWidth = (BitWidth / 8); if (BitWidth % 8) { ByteWidth += 1; } goto DoFunction; } /* * Find the region's address space and length before searching * the linked list. */ BaseAddress = RegionObject->Region.Address; Length = (ACPI_SIZE) RegionObject->Region.Length; SpaceId = RegionObject->Region.SpaceId; ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Operation Region request on %s at 0x%X\n", AcpiUtGetRegionName (RegionObject->Region.SpaceId), (UINT32) Address)); switch (SpaceId) { case ACPI_ADR_SPACE_SYSTEM_IO: /* * For I/O space, exercise the port validation */ switch (Function & ACPI_IO_MASK) { case ACPI_READ: Status = AcpiHwReadPort (Address, (UINT32 *) Value, BitWidth); break; case ACPI_WRITE: Status = AcpiHwWritePort (Address, (UINT32) *Value, BitWidth); break; default: Status = AE_BAD_PARAMETER; break; } if (ACPI_FAILURE (Status)) { return (Status); } /* Now go ahead and simulate the hardware */ break; case ACPI_ADR_SPACE_SMBUS: Length = 0; switch (Function & ACPI_IO_MASK) { case ACPI_READ: switch (Function >> 16) { case AML_FIELD_ATTRIB_SMB_QUICK: case AML_FIELD_ATTRIB_SMB_SEND_RCV: case AML_FIELD_ATTRIB_SMB_BYTE: Length = 1; break; case AML_FIELD_ATTRIB_SMB_WORD: case AML_FIELD_ATTRIB_SMB_WORD_CALL: Length = 2; break; case AML_FIELD_ATTRIB_SMB_BLOCK: case AML_FIELD_ATTRIB_SMB_BLOCK_CALL: Length = 32; break; default: break; } break; case ACPI_WRITE: switch (Function >> 16) { case AML_FIELD_ATTRIB_SMB_QUICK: case AML_FIELD_ATTRIB_SMB_SEND_RCV: case AML_FIELD_ATTRIB_SMB_BYTE: case AML_FIELD_ATTRIB_SMB_WORD: case AML_FIELD_ATTRIB_SMB_BLOCK: Length = 0; break; case AML_FIELD_ATTRIB_SMB_WORD_CALL: Length = 2; break; case AML_FIELD_ATTRIB_SMB_BLOCK_CALL: Length = 32; break; default: break; } break; default: break; } for (i = 0; i < Length; i++) { Buffer[i+2] = (UINT8) (0xA0 + i); } Buffer[0] = 0x7A; Buffer[1] = (UINT8) Length; return (AE_OK); case ACPI_ADR_SPACE_IPMI: /* ACPI 4.0 */ AcpiOsPrintf ("AcpiExec: Received IPMI request: " "Address %X BaseAddress %X Length %X Width %X BufferLength %u\n", (UINT32) Address, (UINT32) BaseAddress, Length, BitWidth, Buffer[1]); /* * Regardless of a READ or WRITE, this handler is passed a 66-byte * buffer in which to return the IPMI status/length/data. * * Return some example data to show use of the bidirectional buffer */ Buffer[0] = 0; /* Status byte */ Buffer[1] = 64; /* Return buffer data length */ Buffer[2] = 0; /* Completion code */ Buffer[3] = 0x34; /* Power measurement */ Buffer[4] = 0x12; /* Power measurement */ Buffer[65] = 0xEE; /* last buffer byte */ return (AE_OK); default: break; } /* * Search through the linked list for this region's buffer */ BufferExists = FALSE; RegionElement = AeRegions.RegionList; if (AeRegions.NumberOfRegions) { while (!BufferExists && RegionElement) { if (RegionElement->Address == BaseAddress && RegionElement->Length == Length && RegionElement->SpaceId == SpaceId) { BufferExists = TRUE; } else { RegionElement = RegionElement->NextRegion; } } } /* * If the Region buffer does not exist, create it now */ if (!BufferExists) { /* * Do the memory allocations first */ RegionElement = AcpiOsAllocate (sizeof (AE_REGION)); if (!RegionElement) { return AE_NO_MEMORY; } RegionElement->Buffer = AcpiOsAllocate (Length); if (!RegionElement->Buffer) { AcpiOsFree (RegionElement); return AE_NO_MEMORY; } /* Initialize the region with the default fill value */ ACPI_MEMSET (RegionElement->Buffer, AcpiGbl_RegionFillValue, Length); RegionElement->Address = BaseAddress; RegionElement->Length = Length; RegionElement->SpaceId = SpaceId; RegionElement->NextRegion = NULL; /* * Increment the number of regions and put this one * at the head of the list as it will probably get accessed * more often anyway. */ AeRegions.NumberOfRegions += 1; if (AeRegions.RegionList) { RegionElement->NextRegion = AeRegions.RegionList; } AeRegions.RegionList = RegionElement; } /* * Calculate the size of the memory copy */ ByteWidth = (BitWidth / 8); if (BitWidth % 8) { ByteWidth += 1; } /* * The buffer exists and is pointed to by RegionElement. * We now need to verify the request is valid and perform the operation. * * NOTE: RegionElement->Length is in bytes, therefore it we compare against * ByteWidth (see above) */ if (((UINT64) Address + ByteWidth) > ((UINT64)(RegionElement->Address) + RegionElement->Length)) { ACPI_WARNING ((AE_INFO, "Request on [%4.4s] is beyond region limit Req-0x%X+0x%X, Base=0x%X, Len-0x%X", (RegionObject->Region.Node)->Name.Ascii, (UINT32) Address, ByteWidth, (UINT32)(RegionElement->Address), RegionElement->Length)); return AE_AML_REGION_LIMIT; } /* * Get BufferValue to point to the "address" in the buffer */ BufferValue = ((UINT8 *) RegionElement->Buffer + ((UINT64) Address - (UINT64) RegionElement->Address)); DoFunction: /* * Perform a read or write to the buffer space */ switch (Function) { case ACPI_READ: /* * Set the pointer Value to whatever is in the buffer */ ACPI_MEMCPY (Value, BufferValue, ByteWidth); break; case ACPI_WRITE: /* * Write the contents of Value to the buffer */ ACPI_MEMCPY (BufferValue, Value, ByteWidth); break; default: return AE_BAD_PARAMETER; } return AE_OK; }
static void OpnDoDefinitionBlock ( ACPI_PARSE_OBJECT *Op) { ACPI_PARSE_OBJECT *Child; ACPI_SIZE Length; ACPI_NATIVE_UINT i; /* * These nodes get stuffed into the table header. They are special * cased when the table is written to the output file. * * Mark all of these nodes as non-usable so they won't get output * as AML opcodes! */ /* Get AML filename. Use it if non-null */ Child = Op->Asl.Child; if (Child->Asl.Value.Buffer && *Child->Asl.Value.Buffer && (Gbl_UseDefaultAmlFilename)) { Gbl_OutputFilenamePrefix = (char *) Child->Asl.Value.Buffer; } Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; /* Signature */ Child = Child->Asl.Next; Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; if (Child->Asl.Value.String) { Gbl_TableSignature = Child->Asl.Value.String; if (ACPI_STRLEN (Gbl_TableSignature) != 4) { AslError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, Child, "Length not exactly 4"); } for (i = 0; i < 4; i++) { if (!isalnum (Gbl_TableSignature[i])) { AslError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, Child, "Contains non-alphanumeric characters"); } } } /* Revision */ Child = Child->Asl.Next; Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; /* * We used the revision to set the integer width earlier */ /* OEMID */ Child = Child->Asl.Next; Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; /* OEM TableID */ Child = Child->Asl.Next; Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; if (Child->Asl.Value.String) { Length = ACPI_STRLEN (Child->Asl.Value.String); Gbl_TableId = AcpiOsAllocate (Length + 1); ACPI_STRCPY (Gbl_TableId, Child->Asl.Value.String); for (i = 0; i < Length; i++) { if (Gbl_TableId[i] == ' ') { Gbl_TableId[i] = 0; break; } } } /* OEM Revision */ Child = Child->Asl.Next; Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; }
ACPI_STATUS AcpiUtInitializeBuffer ( ACPI_BUFFER *Buffer, ACPI_SIZE RequiredLength) { ACPI_SIZE InputBufferLength; /* Parameter validation */ if (!Buffer || !RequiredLength) { return (AE_BAD_PARAMETER); } /* * Buffer->Length is used as both an input and output parameter. Get the * input actual length and set the output required buffer length. */ InputBufferLength = Buffer->Length; Buffer->Length = RequiredLength; /* * The input buffer length contains the actual buffer length, or the type * of buffer to be allocated by this routine. */ switch (InputBufferLength) { case ACPI_NO_BUFFER: /* Return the exception (and the required buffer length) */ return (AE_BUFFER_OVERFLOW); case ACPI_ALLOCATE_BUFFER: /* * Allocate a new buffer. We directectly call AcpiOsAllocate here to * purposefully bypass the (optionally enabled) internal allocation * tracking mechanism since we only want to track internal * allocations. Note: The caller should use AcpiOsFree to free this * buffer created via ACPI_ALLOCATE_BUFFER. */ Buffer->Pointer = AcpiOsAllocate (RequiredLength); break; case ACPI_ALLOCATE_LOCAL_BUFFER: /* Allocate a new buffer with local interface to allow tracking */ Buffer->Pointer = ACPI_ALLOCATE (RequiredLength); break; default: /* Existing buffer: Validate the size of the buffer */ if (InputBufferLength < RequiredLength) { return (AE_BUFFER_OVERFLOW); } break; } /* Validate allocation from above or input buffer pointer */ if (!Buffer->Pointer) { return (AE_NO_MEMORY); } /* Have a valid buffer, clear it */ ACPI_MEMSET (Buffer->Pointer, 0, RequiredLength); return (AE_OK); }
ACPI_TABLE_HEADER * OsGetTable ( char *Signature) { HKEY Handle = NULL; ULONG i; LONG Status; ULONG Type; ULONG NameSize; ULONG DataSize; HKEY SubKey; ACPI_TABLE_HEADER *ReturnTable; /* Get a handle to the table key */ while (1) { ACPI_STRCPY (KeyBuffer, "HARDWARE\\ACPI\\"); ACPI_STRCAT (KeyBuffer, Signature); Status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, KeyBuffer, 0L, KEY_ALL_ACCESS, &Handle); if (Status != ERROR_SUCCESS) { /* * Somewhere along the way, MS changed the registry entry for * the FADT from * HARDWARE/ACPI/FACP to * HARDWARE/ACPI/FADT. * * This code allows for both. */ if (ACPI_COMPARE_NAME (Signature, "FACP")) { Signature = "FADT"; } else { AcpiOsPrintf ("Could not find %s in registry at %s\n", Signature, KeyBuffer); return (NULL); } } else { break; } } /* Actual data for table is down a couple levels */ for (i = 0; ;) { Status = RegEnumKey (Handle, i, KeyBuffer, sizeof (KeyBuffer)); i += 1; if (Status == ERROR_NO_MORE_ITEMS) { break; } Status = RegOpenKey (Handle, KeyBuffer, &SubKey); if (Status != ERROR_SUCCESS) { AcpiOsPrintf ("Could not open %s entry\n", Signature); return (NULL); } RegCloseKey (Handle); Handle = SubKey; i = 0; } /* Find the (binary) table entry */ for (i = 0; ;) { NameSize = sizeof (KeyBuffer); Status = RegEnumValue (Handle, i, KeyBuffer, &NameSize, NULL, &Type, NULL, 0); if (Status != ERROR_SUCCESS) { AcpiOsPrintf ("Could not get %s registry entry\n", Signature); return (NULL); } if (Type == REG_BINARY) { break; } i += 1; } /* Get the size of the table */ Status = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL, NULL, &DataSize); if (Status != ERROR_SUCCESS) { AcpiOsPrintf ("Could not read the %s table size\n", Signature); return (NULL); } /* Allocate a new buffer for the table */ ReturnTable = AcpiOsAllocate (DataSize); if (!ReturnTable) { goto Cleanup; } /* Get the actual table from the registry */ Status = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL, (UCHAR *) ReturnTable, &DataSize); if (Status != ERROR_SUCCESS) { AcpiOsPrintf ("Could not read %s data\n", Signature); AcpiOsFree (ReturnTable); return (NULL); } Cleanup: RegCloseKey (Handle); return (ReturnTable); }
ACPI_STATUS AeBuildLocalTables ( ACPI_NEW_TABLE_DESC *ListHead) { UINT32 TableCount = 1; ACPI_PHYSICAL_ADDRESS DsdtAddress = 0; UINT32 XsdtSize; ACPI_NEW_TABLE_DESC *NextTable; UINT32 NextIndex; ACPI_TABLE_FADT *ExternalFadt = NULL; /* * Update the table count. For the DSDT, it is not put into the XSDT. * For the FADT, this table is already accounted for since we usually * install a local FADT. */ NextTable = ListHead; while (NextTable) { if (!ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT) && !ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT)) { TableCount++; } NextTable = NextTable->Next; } XsdtSize = (((TableCount + 1) * sizeof (UINT64)) + sizeof (ACPI_TABLE_HEADER)); if (AcpiGbl_LoadTestTables) { XsdtSize += BASE_XSDT_SIZE; } /* Build an XSDT */ LocalXSDT = AcpiOsAllocate (XsdtSize); if (!LocalXSDT) { return (AE_NO_MEMORY); } memset (LocalXSDT, 0, XsdtSize); LocalXSDT->TableOffsetEntry[0] = ACPI_PTR_TO_PHYSADDR (&LocalFADT); NextIndex = 1; /* * Install the user tables. The DSDT must be installed in the FADT. * All other tables are installed directly into the XSDT. */ NextTable = ListHead; while (NextTable) { /* * Incoming DSDT or FADT are special cases. All other tables are * just immediately installed into the XSDT. */ if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT)) { if (DsdtAddress) { printf ("Already found a DSDT, only one allowed\n"); return (AE_ALREADY_EXISTS); } /* The incoming user table is a DSDT */ DsdtAddress = ACPI_PTR_TO_PHYSADDR (NextTable->Table); DsdtToInstallOverride = NextTable->Table; } else if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT)) { ExternalFadt = ACPI_CAST_PTR (ACPI_TABLE_FADT, NextTable->Table); LocalXSDT->TableOffsetEntry[0] = ACPI_PTR_TO_PHYSADDR (NextTable->Table); } else { /* Install the table in the XSDT */ LocalXSDT->TableOffsetEntry[NextIndex] = ACPI_PTR_TO_PHYSADDR (NextTable->Table); NextIndex++; } NextTable = NextTable->Next; } /* Install the optional extra local tables */ if (AcpiGbl_LoadTestTables) { LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&LocalTEST); LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&LocalBADTABLE); /* Install two SSDTs to test multiple table support */ LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&Ssdt1Code); LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&Ssdt2Code); /* Install the OEM1 table to test LoadTable */ LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&Oem1Code); /* Install the OEMx table to test LoadTable */ LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&OemxCode); /* Install the ECDT table to test _REG */ LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&EcdtCode); /* Install two UEFIs to test multiple table support */ LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&Uefi1Code); LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&Uefi2Code); } /* Build an RSDP. Contains a valid XSDT only, no RSDT */ memset (&LocalRSDP, 0, sizeof (ACPI_TABLE_RSDP)); ACPI_MAKE_RSDP_SIG (LocalRSDP.Signature); memcpy (LocalRSDP.OemId, "Intel", 6); LocalRSDP.Revision = 2; LocalRSDP.XsdtPhysicalAddress = ACPI_PTR_TO_PHYSADDR (LocalXSDT); LocalRSDP.Length = sizeof (ACPI_TABLE_RSDP); /* Set checksums for both XSDT and RSDP */ AeInitializeTableHeader ((void *) LocalXSDT, ACPI_SIG_XSDT, XsdtSize); LocalRSDP.Checksum = 0; LocalRSDP.Checksum = (UINT8) -AcpiTbChecksum ( (void *) &LocalRSDP, ACPI_RSDP_CHECKSUM_LENGTH); if (!DsdtAddress) { /* Use the local DSDT because incoming table(s) are all SSDT(s) */ DsdtAddress = ACPI_PTR_TO_PHYSADDR (LocalDsdtCode); DsdtToInstallOverride = ACPI_CAST_PTR (ACPI_TABLE_HEADER, LocalDsdtCode); } /* * Build an FADT. There are three options for the FADT: * 1) Incoming external FADT specified on the command line * 2) A "hardware reduced" local FADT * 3) A fully featured local FADT */ memset (&LocalFADT, 0, sizeof (ACPI_TABLE_FADT)); if (ExternalFadt) { /* * Use the external FADT, but we must update the DSDT/FACS * addresses as well as the checksum */ ExternalFadt->Dsdt = (UINT32) DsdtAddress; if (!AcpiGbl_ReducedHardware) { ExternalFadt->Facs = ACPI_PTR_TO_PHYSADDR (&LocalFACS); } /* * If there room in the FADT for the XDsdt and XFacs 64-bit * pointers, use them. */ if (ExternalFadt->Header.Length > ACPI_PTR_DIFF ( &ExternalFadt->XDsdt, ExternalFadt)) { ExternalFadt->Dsdt = 0; ExternalFadt->Facs = 0; ExternalFadt->XDsdt = DsdtAddress; if (!AcpiGbl_ReducedHardware) { ExternalFadt->XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS); } } /* Complete the external FADT with the checksum */ ExternalFadt->Header.Checksum = 0; ExternalFadt->Header.Checksum = (UINT8) -AcpiTbChecksum ( (void *) ExternalFadt, ExternalFadt->Header.Length); } else if (AcpiGbl_UseHwReducedFadt) { memcpy (&LocalFADT, HwReducedFadtCode, ACPI_FADT_V5_SIZE); LocalFADT.Dsdt = 0; LocalFADT.XDsdt = DsdtAddress; } else { /* * Build a local FADT so we can test the hardware/event init */ LocalFADT.Header.Revision = 5; /* Setup FADT header and DSDT/FACS addresses */ LocalFADT.Dsdt = 0; LocalFADT.Facs = 0; LocalFADT.XDsdt = DsdtAddress; LocalFADT.XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS); /* Miscellaneous FADT fields */ LocalFADT.Gpe0BlockLength = 0x08; LocalFADT.Gpe0Block = 0x00001234; LocalFADT.Gpe1BlockLength = 0x80; LocalFADT.Gpe1Block = 0x00005678; LocalFADT.Gpe1Base = 100; LocalFADT.Pm1EventLength = 4; LocalFADT.Pm1aEventBlock = 0x00001aaa; LocalFADT.Pm1bEventBlock = 0x00001bbb; LocalFADT.Pm1ControlLength = 2; LocalFADT.Pm1aControlBlock = 0xB0; LocalFADT.PmTimerLength = 4; LocalFADT.PmTimerBlock = 0xA0; LocalFADT.Pm2ControlBlock = 0xC0; LocalFADT.Pm2ControlLength = 1; /* Setup one example X-64 GAS field */ LocalFADT.XPm1bEventBlock.SpaceId = ACPI_ADR_SPACE_SYSTEM_IO; LocalFADT.XPm1bEventBlock.Address = LocalFADT.Pm1bEventBlock; LocalFADT.XPm1bEventBlock.BitWidth = (UINT8) ACPI_MUL_8 (LocalFADT.Pm1EventLength); } AeInitializeTableHeader ((void *) &LocalFADT, ACPI_SIG_FADT, sizeof (ACPI_TABLE_FADT)); /* Build a FACS */ memset (&LocalFACS, 0, sizeof (ACPI_TABLE_FACS)); ACPI_MOVE_NAME (LocalFACS.Signature, ACPI_SIG_FACS); LocalFACS.Length = sizeof (ACPI_TABLE_FACS); LocalFACS.GlobalLock = 0x11AA0011; /* Build the optional local tables */ if (AcpiGbl_LoadTestTables) { /* * Build a fake table [TEST] so that we make sure that the * ACPICA core ignores it */ memset (&LocalTEST, 0, sizeof (ACPI_TABLE_HEADER)); ACPI_MOVE_NAME (LocalTEST.Signature, "TEST"); LocalTEST.Revision = 1; LocalTEST.Length = sizeof (ACPI_TABLE_HEADER); LocalTEST.Checksum = 0; LocalTEST.Checksum = (UINT8) -AcpiTbChecksum ( (void *) &LocalTEST, LocalTEST.Length); /* * Build a fake table with a bad signature [BAD!] so that we make * sure that the ACPICA core ignores it */ memset (&LocalBADTABLE, 0, sizeof (ACPI_TABLE_HEADER)); ACPI_MOVE_NAME (LocalBADTABLE.Signature, "BAD!"); LocalBADTABLE.Revision = 1; LocalBADTABLE.Length = sizeof (ACPI_TABLE_HEADER); LocalBADTABLE.Checksum = 0; LocalBADTABLE.Checksum = (UINT8) -AcpiTbChecksum ( (void *) &LocalBADTABLE, LocalBADTABLE.Length); } return (AE_OK); }
static int NsDumpEntireNamespace ( char *AmlFilename) { ACPI_STATUS Status; ACPI_TABLE_HEADER *Table = NULL; UINT32 TableCount = 0; AE_TABLE_DESC *TableDesc; ACPI_HANDLE Handle; /* Open the binary AML file and read the entire table */ Status = AcpiUtReadTableFromFile (AmlFilename, &Table); if (ACPI_FAILURE (Status)) { printf ("**** Could not get input table %s, %s\n", AmlFilename, AcpiFormatException (Status)); return (-1); } /* Table must be a DSDT. SSDTs are not currently supported */ if (!ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT)) { printf ("**** Input table signature is [%4.4s], must be [DSDT]\n", Table->Signature); return (-1); } /* * Allocate and link a table descriptor (allows for future expansion to * multiple input files) */ TableDesc = AcpiOsAllocate (sizeof (AE_TABLE_DESC)); TableDesc->Table = Table; TableDesc->Next = AeTableListHead; AeTableListHead = TableDesc; TableCount++; /* * Build a local XSDT with all tables. Normally, here is where the * RSDP search is performed to find the ACPI tables */ Status = AeBuildLocalTables (TableCount, AeTableListHead); if (ACPI_FAILURE (Status)) { return (-1); } /* Initialize table manager, get XSDT */ Status = AcpiInitializeTables (Tables, ACPI_MAX_INIT_TABLES, TRUE); if (ACPI_FAILURE (Status)) { printf ("**** Could not initialize ACPI table manager, %s\n", AcpiFormatException (Status)); return (-1); } /* Reallocate root table to dynamic memory */ Status = AcpiReallocateRootTable (); if (ACPI_FAILURE (Status)) { printf ("**** Could not reallocate root table, %s\n", AcpiFormatException (Status)); return (-1); } /* Load the ACPI namespace */ Status = AcpiLoadTables (); if (ACPI_FAILURE (Status)) { printf ("**** Could not load ACPI tables, %s\n", AcpiFormatException (Status)); return (-1); } /* * Enable ACPICA. These calls don't do much for this * utility, since we only dump the namespace. There is no * hardware or event manager code underneath. */ Status = AcpiEnableSubsystem ( ACPI_NO_ACPI_ENABLE | ACPI_NO_ADDRESS_SPACE_INIT | ACPI_NO_EVENT_INIT | ACPI_NO_HANDLER_INIT); if (ACPI_FAILURE (Status)) { printf ("**** Could not EnableSubsystem, %s\n", AcpiFormatException (Status)); return (-1); } Status = AcpiInitializeObjects ( ACPI_NO_ADDRESS_SPACE_INIT | ACPI_NO_DEVICE_INIT | ACPI_NO_EVENT_INIT); if (ACPI_FAILURE (Status)) { printf ("**** Could not InitializeObjects, %s\n", AcpiFormatException (Status)); return (-1); } /* * Perform a namespace walk to dump the contents */ AcpiOsPrintf ("\nACPI Namespace:\n"); AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, ACPI_UINT32_MAX, ACPI_OWNER_ID_MAX, AcpiGbl_RootNode); /* Example: get a handle to the _GPE scope */ Status = AcpiGetHandle (NULL, "\\_GPE", &Handle); AE_CHECK_OK (AcpiGetHandle, Status); return (0); }
void AcpiDbCreateExecutionThreads ( char *NumThreadsArg, char *NumLoopsArg, char *MethodNameArg) { ACPI_STATUS Status; UINT32 NumThreads; UINT32 NumLoops; UINT32 i; UINT32 Size; ACPI_MUTEX MainThreadGate; ACPI_MUTEX ThreadCompleteGate; ACPI_MUTEX InfoGate; /* Get the arguments */ NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0); NumLoops = ACPI_STRTOUL (NumLoopsArg, NULL, 0); if (!NumThreads || !NumLoops) { AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n", NumThreads, NumLoops); return; } /* * Create the semaphore for synchronization of * the created threads with the main thread. */ Status = AcpiOsCreateSemaphore (1, 0, &MainThreadGate); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not create semaphore for synchronization with the main thread, %s\n", AcpiFormatException (Status)); return; } /* * Create the semaphore for synchronization * between the created threads. */ Status = AcpiOsCreateSemaphore (1, 1, &ThreadCompleteGate); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not create semaphore for synchronization between the created threads, %s\n", AcpiFormatException (Status)); (void) AcpiOsDeleteSemaphore (MainThreadGate); return; } Status = AcpiOsCreateSemaphore (1, 1, &InfoGate); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not create semaphore for synchronization of AcpiGbl_DbMethodInfo, %s\n", AcpiFormatException (Status)); (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); (void) AcpiOsDeleteSemaphore (MainThreadGate); return; } ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); /* Array to store IDs of threads */ AcpiGbl_DbMethodInfo.NumThreads = NumThreads; Size = sizeof (ACPI_THREAD_ID) * AcpiGbl_DbMethodInfo.NumThreads; AcpiGbl_DbMethodInfo.Threads = AcpiOsAllocate (Size); if (AcpiGbl_DbMethodInfo.Threads == NULL) { AcpiOsPrintf ("No memory for thread IDs array\n"); (void) AcpiOsDeleteSemaphore (MainThreadGate); (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); (void) AcpiOsDeleteSemaphore (InfoGate); return; } ACPI_MEMSET (AcpiGbl_DbMethodInfo.Threads, 0, Size); /* Setup the context to be passed to each thread */ AcpiGbl_DbMethodInfo.Name = MethodNameArg; AcpiGbl_DbMethodInfo.Flags = 0; AcpiGbl_DbMethodInfo.NumLoops = NumLoops; AcpiGbl_DbMethodInfo.MainThreadGate = MainThreadGate; AcpiGbl_DbMethodInfo.ThreadCompleteGate = ThreadCompleteGate; AcpiGbl_DbMethodInfo.InfoGate = InfoGate; /* Init arguments to be passed to method */ AcpiGbl_DbMethodInfo.InitArgs = 1; AcpiGbl_DbMethodInfo.Args = AcpiGbl_DbMethodInfo.Arguments; AcpiGbl_DbMethodInfo.Arguments[0] = AcpiGbl_DbMethodInfo.NumThreadsStr; AcpiGbl_DbMethodInfo.Arguments[1] = AcpiGbl_DbMethodInfo.IdOfThreadStr; AcpiGbl_DbMethodInfo.Arguments[2] = AcpiGbl_DbMethodInfo.IndexOfThreadStr; AcpiGbl_DbMethodInfo.Arguments[3] = NULL; AcpiGbl_DbMethodInfo.Types = AcpiGbl_DbMethodInfo.ArgTypes; AcpiGbl_DbMethodInfo.ArgTypes[0] = ACPI_TYPE_INTEGER; AcpiGbl_DbMethodInfo.ArgTypes[1] = ACPI_TYPE_INTEGER; AcpiGbl_DbMethodInfo.ArgTypes[2] = ACPI_TYPE_INTEGER; AcpiDbUint32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr); Status = AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); if (ACPI_FAILURE (Status)) { goto CleanupAndExit; } /* Get the NS node, determines existence also */ Status = AcpiGetHandle (NULL, AcpiGbl_DbMethodInfo.Pathname, &AcpiGbl_DbMethodInfo.Method); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("%s Could not get handle for %s\n", AcpiFormatException (Status), AcpiGbl_DbMethodInfo.Pathname); goto CleanupAndExit; } /* Create the threads */ AcpiOsPrintf ("Creating %X threads to execute %X times each\n", NumThreads, NumLoops); for (i = 0; i < (NumThreads); i++) { Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbMethodThread, &AcpiGbl_DbMethodInfo); if (ACPI_FAILURE (Status)) { break; } } /* Wait for all threads to complete */ (void) AcpiOsWaitSemaphore (MainThreadGate, 1, ACPI_WAIT_FOREVER); AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads); AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); CleanupAndExit: /* Cleanup and exit */ (void) AcpiOsDeleteSemaphore (MainThreadGate); (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); (void) AcpiOsDeleteSemaphore (InfoGate); AcpiOsFree (AcpiGbl_DbMethodInfo.Threads); AcpiGbl_DbMethodInfo.Threads = NULL; }
ACPI_STATUS AeBuildLocalTables ( UINT32 TableCount, AE_TABLE_DESC *TableList) { ACPI_PHYSICAL_ADDRESS DsdtAddress = 0; UINT32 XsdtSize; AE_TABLE_DESC *NextTable; UINT32 NextIndex; ACPI_TABLE_FADT *ExternalFadt = NULL; /* * Update the table count. For DSDT, it is not put into the XSDT. For * FADT, this is already accounted for since we usually install a * local FADT. */ NextTable = TableList; while (NextTable) { if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT) || ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT)) { TableCount--; } NextTable = NextTable->Next; } XsdtSize = BASE_XSDT_SIZE + (TableCount * sizeof (UINT64)); /* Build an XSDT */ LocalXSDT = AcpiOsAllocate (XsdtSize); if (!LocalXSDT) { return (AE_NO_MEMORY); } ACPI_MEMSET (LocalXSDT, 0, XsdtSize); ACPI_MOVE_NAME (LocalXSDT->Header.Signature, ACPI_SIG_XSDT); LocalXSDT->Header.Length = XsdtSize; LocalXSDT->Header.Revision = 1; LocalXSDT->TableOffsetEntry[0] = ACPI_PTR_TO_PHYSADDR (&LocalFADT); /* * Install the user tables. The DSDT must be installed in the FADT. * All other tables are installed directly into the XSDT. */ NextIndex = BASE_XSDT_TABLES; NextTable = TableList; while (NextTable) { /* * Incoming DSDT or FADT are special cases. All other tables are * just immediately installed into the XSDT. */ if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT)) { if (DsdtAddress) { printf ("Already found a DSDT, only one allowed\n"); return (AE_ALREADY_EXISTS); } /* The incoming user table is a DSDT */ DsdtAddress = ACPI_PTR_TO_PHYSADDR (NextTable->Table); } else if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT)) { ExternalFadt = ACPI_CAST_PTR (ACPI_TABLE_FADT, NextTable->Table); LocalXSDT->TableOffsetEntry[2] = ACPI_PTR_TO_PHYSADDR (NextTable->Table); } else { /* Install the table in the XSDT */ LocalXSDT->TableOffsetEntry[NextIndex] = ACPI_PTR_TO_PHYSADDR (NextTable->Table); NextIndex++; } NextTable = NextTable->Next; } /* Build an RSDP */ ACPI_MEMSET (&LocalRSDP, 0, sizeof (ACPI_TABLE_RSDP)); ACPI_MAKE_RSDP_SIG (LocalRSDP.Signature); ACPI_MEMCPY (LocalRSDP.OemId, "I_TEST", 6); LocalRSDP.Revision = 2; LocalRSDP.XsdtPhysicalAddress = ACPI_PTR_TO_PHYSADDR (LocalXSDT); LocalRSDP.Length = sizeof (ACPI_TABLE_XSDT); /* Set checksums for both XSDT and RSDP */ LocalXSDT->Header.Checksum = (UINT8) -AcpiTbChecksum ( (void *) LocalXSDT, LocalXSDT->Header.Length); LocalRSDP.Checksum = (UINT8) -AcpiTbChecksum ( (void *) &LocalRSDP, ACPI_RSDP_CHECKSUM_LENGTH); if (!DsdtAddress) { return (AE_SUPPORT); } if (ExternalFadt) { /* * Use the external FADT, but we must update the DSDT/FACS addresses * as well as the checksum */ ExternalFadt->Dsdt = DsdtAddress; ExternalFadt->Facs = ACPI_PTR_TO_PHYSADDR (&LocalFACS); if (ExternalFadt->Header.Length > ACPI_PTR_DIFF (&ExternalFadt->XDsdt, ExternalFadt)) { ExternalFadt->XDsdt = DsdtAddress; ExternalFadt->XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS); } /* Complete the FADT with the checksum */ ExternalFadt->Header.Checksum = 0; ExternalFadt->Header.Checksum = (UINT8) -AcpiTbChecksum ( (void *) ExternalFadt, ExternalFadt->Header.Length); } else { /* * Build a local FADT so we can test the hardware/event init */ ACPI_MEMSET (&LocalFADT, 0, sizeof (ACPI_TABLE_FADT)); ACPI_MOVE_NAME (LocalFADT.Header.Signature, ACPI_SIG_FADT); /* Setup FADT header and DSDT/FACS addresses */ LocalFADT.Dsdt = 0; LocalFADT.Facs = 0; LocalFADT.XDsdt = DsdtAddress; LocalFADT.XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS); LocalFADT.Header.Revision = 3; LocalFADT.Header.Length = sizeof (ACPI_TABLE_FADT); /* Miscellaneous FADT fields */ LocalFADT.Gpe0BlockLength = 16; LocalFADT.Gpe0Block = 0x00001234; LocalFADT.Gpe1BlockLength = 6; LocalFADT.Gpe1Block = 0x00005678; LocalFADT.Gpe1Base = 96; LocalFADT.Pm1EventLength = 4; LocalFADT.Pm1aEventBlock = 0x00001aaa; LocalFADT.Pm1bEventBlock = 0x00001bbb; LocalFADT.Pm1ControlLength = 2; LocalFADT.Pm1aControlBlock = 0xB0; LocalFADT.PmTimerLength = 4; LocalFADT.PmTimerBlock = 0xA0; LocalFADT.Pm2ControlBlock = 0xC0; LocalFADT.Pm2ControlLength = 1; /* Setup one example X-64 field */ LocalFADT.XPm1bEventBlock.SpaceId = ACPI_ADR_SPACE_SYSTEM_IO; LocalFADT.XPm1bEventBlock.Address = LocalFADT.Pm1bEventBlock; LocalFADT.XPm1bEventBlock.BitWidth = (UINT8) ACPI_MUL_8 (LocalFADT.Pm1EventLength); /* Complete the FADT with the checksum */ LocalFADT.Header.Checksum = 0; LocalFADT.Header.Checksum = (UINT8) -AcpiTbChecksum ( (void *) &LocalFADT, LocalFADT.Header.Length); } /* Build a FACS */ ACPI_MEMSET (&LocalFACS, 0, sizeof (ACPI_TABLE_FACS)); ACPI_MOVE_NAME (LocalFACS.Signature, ACPI_SIG_FACS); LocalFACS.Length = sizeof (ACPI_TABLE_FACS); LocalFACS.GlobalLock = 0x11AA0011; return (AE_OK); }