int ApDumpTableByAddress ( char *AsciiAddress) { ACPI_PHYSICAL_ADDRESS Address; ACPI_TABLE_HEADER *Table; ACPI_STATUS Status; int TableStatus; UINT64 LongAddress; /* Convert argument to an integer physical address */ Status = AcpiUtStrtoul64 (AsciiAddress, 0, &LongAddress); if (ACPI_FAILURE (Status)) { AcpiLogError ("%s: Could not convert to a physical address\n", AsciiAddress); return (-1); } Address = (ACPI_PHYSICAL_ADDRESS) LongAddress; Status = AcpiOsGetTableByAddress (Address, &Table); if (ACPI_FAILURE (Status)) { AcpiLogError ("Could not get table at 0x%8.8X%8.8X, %s\n", ACPI_FORMAT_UINT64 (Address), AcpiFormatException (Status)); return (-1); } TableStatus = ApDumpTableBuffer (Table, 0, Address); ACPI_FREE (Table); return (TableStatus); }
BOOLEAN ApIsValidHeader ( ACPI_TABLE_HEADER *Table) { if (!ACPI_VALIDATE_RSDP_SIG (Table->Signature)) { /* Make sure signature is all ASCII and a valid ACPI name */ if (!AcpiUtValidAcpiName (Table->Signature)) { AcpiLogError ("Table signature (0x%8.8X) is invalid\n", *(UINT32 *) Table->Signature); return (FALSE); } /* Check for minimum table length */ if (Table->Length < sizeof (ACPI_TABLE_HEADER)) { AcpiLogError ("Table length (0x%8.8X) is invalid\n", Table->Length); return (FALSE); } } return (TRUE); }
ACPI_TABLE_HEADER * ApGetTableFromFile ( char *Pathname, UINT32 *OutFileSize) { ACPI_TABLE_HEADER *Buffer = NULL; ACPI_FILE File; UINT32 FileSize; size_t Actual; /* Must use binary mode */ File = AcpiOsOpenFile (Pathname, ACPI_FILE_READING | ACPI_FILE_BINARY); if (!File) { AcpiLogError ("Could not open input file: %s\n", Pathname); return (NULL); } /* Need file size to allocate a buffer */ FileSize = CmGetFileSize (File); if (FileSize == ACPI_UINT32_MAX) { AcpiLogError ( "Could not get input file size: %s\n", Pathname); goto Cleanup; } /* Allocate a buffer for the entire file */ Buffer = ACPI_ALLOCATE_ZEROED (FileSize); if (!Buffer) { AcpiLogError ( "Could not allocate file buffer of size: %u\n", FileSize); goto Cleanup; } /* Read the entire file */ Actual = AcpiOsReadFile (File, Buffer, 1, FileSize); if (Actual != FileSize) { AcpiLogError ( "Could not read input file: %s\n", Pathname); ACPI_FREE (Buffer); Buffer = NULL; goto Cleanup; } *OutFileSize = FileSize; Cleanup: AcpiOsCloseFile (File); return (Buffer); }
int ApDumpAllTables ( void) { ACPI_TABLE_HEADER *Table; UINT32 Instance = 0; ACPI_PHYSICAL_ADDRESS Address; ACPI_STATUS Status; int TableStatus; UINT32 i; /* Get and dump all available ACPI tables */ for (i = 0; i < AP_MAX_ACPI_FILES; i++) { Status = AcpiOsGetTableByIndex (i, &Table, &Instance, &Address); if (ACPI_FAILURE (Status)) { /* AE_LIMIT means that no more tables are available */ if (Status == AE_LIMIT) { return (0); } else if (i == 0) { AcpiLogError ("Could not get ACPI tables, %s\n", AcpiFormatException (Status)); return (-1); } else { AcpiLogError ("Could not get ACPI table at index %u, %s\n", i, AcpiFormatException (Status)); continue; } } TableStatus = ApDumpTableBuffer (Table, Instance, Address); ACPI_FREE (Table); if (TableStatus) { break; } } /* Something seriously bad happened if the loop terminates here */ return (-1); }
UINT32 CmGetFileSize ( ACPI_FILE File) { long FileSize; long CurrentOffset; ACPI_STATUS Status; /* Save the current file pointer, seek to EOF to obtain file size */ CurrentOffset = AcpiOsGetFileOffset (File); if (CurrentOffset < 0) { goto OffsetError; } Status = AcpiOsSetFileOffset (File, 0, ACPI_FILE_END); if (ACPI_FAILURE (Status)) { goto SeekError; } FileSize = AcpiOsGetFileOffset (File); if (FileSize < 0) { goto OffsetError; } /* Restore original file pointer */ Status = AcpiOsSetFileOffset (File, CurrentOffset, ACPI_FILE_BEGIN); if (ACPI_FAILURE (Status)) { goto SeekError; } return ((UINT32) FileSize); OffsetError: AcpiLogError ("Could not get file offset"); return (ACPI_UINT32_MAX); SeekError: AcpiLogError ("Could not set file offset"); return (ACPI_UINT32_MAX); }
int ApOpenOutputFile ( char *Pathname) { ACPI_FILE File; /* If file exists, prompt for overwrite */ if (ApIsExistingFile (Pathname) != 0) { return (-1); } /* Point stdout to the file */ File = AcpiOsOpenFile (Pathname, ACPI_FILE_WRITING); if (!File) { AcpiLogError ("Could not open output file: %s\n", Pathname); return (-1); } /* Save the file and path */ Gbl_OutputFile = File; Gbl_OutputFilename = Pathname; return (0); }
BOOLEAN ApIsValidChecksum ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; ACPI_TABLE_RSDP *Rsdp; if (ACPI_VALIDATE_RSDP_SIG (Table->Signature)) { /* * Checksum for RSDP. * Note: Other checksums are computed during the table dump. */ Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Table); Status = AcpiTbValidateRsdp (Rsdp); } else { Status = AcpiTbVerifyChecksum (Table, Table->Length); } if (ACPI_FAILURE (Status)) { AcpiLogError ("%4.4s: Warning: wrong checksum in table\n", Table->Signature); } return (AE_OK); }
int ApDumpTableFromFile ( char *Pathname) { ACPI_TABLE_HEADER *Table; UINT32 FileSize = 0; int TableStatus = -1; /* Get the entire ACPI table from the file */ Table = ApGetTableFromFile (Pathname, &FileSize); if (!Table) { return (-1); } /* File must be at least as long as the table length */ if (Table->Length > FileSize) { AcpiLogError ( "Table length (0x%X) is too large for input file (0x%X) %s\n", Table->Length, FileSize, Pathname); goto Exit; } if (Gbl_VerboseMode) { AcpiLogError ( "Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n", Pathname, Table->Signature, FileSize, FileSize); } TableStatus = ApDumpTableBuffer (Table, 0, 0); Exit: ACPI_FREE (Table); return (TableStatus); }
void * AcpiOsAllocate ( ACPI_SIZE Size) { EFI_STATUS EfiStatus; void *Mem; EfiStatus = uefi_call_wrapper (BS->AllocatePool, 3, EfiLoaderData, Size, &Mem); if (EFI_ERROR (EfiStatus)) { AcpiLogError ("EFI_BOOT_SERVICES->AllocatePool(EfiLoaderData) failure.\n"); return (NULL); } return (Mem); }
static int ApInsertAction ( char *Argument, UINT32 ToBeDone) { /* Insert action and check for table overflow */ ActionTable [CurrentAction].Argument = Argument; ActionTable [CurrentAction].ToBeDone = ToBeDone; CurrentAction++; if (CurrentAction > AP_MAX_ACTIONS) { AcpiLogError ("Too many table options (max %u)\n", AP_MAX_ACTIONS); return (-1); } return (0); }
static int ApIsExistingFile ( char *Pathname) { #ifndef _GNU_EFI struct stat StatInfo; if (!stat (Pathname, &StatInfo)) { AcpiLogError ("Target path already exists, overwrite? [y|n] "); if (getchar () != 'y') { return (-1); } } #endif return 0; }
int AcpiOsReadFile ( ACPI_FILE File, void *Buffer, ACPI_SIZE Size, ACPI_SIZE Count) { int Length = -1; EFI_FILE_HANDLE EfiFile; UINTN ReadSize; EFI_STATUS EfiStatus; if (File == ACPI_FILE_OUT || File == ACPI_FILE_ERR) { } else { EfiFile = (EFI_FILE_HANDLE) File; if (!EfiFile) { goto ErrorExit; } ReadSize = Size * Count; EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Read, 3, EfiFile, &ReadSize, Buffer); if (EFI_ERROR (EfiStatus)) { AcpiLogError ("EFI_FILE_HANDLE->Read() failure.\n"); goto ErrorExit; } Length = ReadSize; } ErrorExit: return (Length); }
int ApWriteToBinaryFile ( ACPI_TABLE_HEADER *Table, UINT32 Instance) { char Filename[ACPI_NAME_SIZE + 16]; char InstanceStr [16]; ACPI_FILE File; size_t Actual; UINT32 TableLength; /* Obtain table length */ TableLength = ApGetTableLength (Table); /* Construct lower-case filename from the table local signature */ if (ACPI_VALIDATE_RSDP_SIG (Table->Signature)) { ACPI_MOVE_NAME (Filename, ACPI_RSDP_NAME); } else { ACPI_MOVE_NAME (Filename, Table->Signature); } Filename[0] = (char) ACPI_TOLOWER (Filename[0]); Filename[1] = (char) ACPI_TOLOWER (Filename[1]); Filename[2] = (char) ACPI_TOLOWER (Filename[2]); Filename[3] = (char) ACPI_TOLOWER (Filename[3]); Filename[ACPI_NAME_SIZE] = 0; /* Handle multiple SSDTs - create different filenames for each */ if (Instance > 0) { AcpiUtSnprintf (InstanceStr, sizeof (InstanceStr), "%u", Instance); ACPI_STRCAT (Filename, InstanceStr); } ACPI_STRCAT (Filename, ACPI_TABLE_FILE_SUFFIX); if (Gbl_VerboseMode) { AcpiLogError ( "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n", Table->Signature, Filename, Table->Length, Table->Length); } /* Open the file and dump the entire table in binary mode */ File = AcpiOsOpenFile (Filename, ACPI_FILE_WRITING | ACPI_FILE_BINARY); if (!File) { AcpiLogError ("Could not open output file: %s\n", Filename); return (-1); } Actual = AcpiOsWriteFile (File, Table, 1, TableLength); if (Actual != TableLength) { AcpiLogError ("Error writing binary output file: %s\n", Filename); AcpiOsCloseFile (File); return (-1); } AcpiOsCloseFile (File); return (0); }
int ApDumpTableByName ( char *Signature) { char LocalSignature [ACPI_NAME_SIZE + 1]; UINT32 Instance; ACPI_TABLE_HEADER *Table; ACPI_PHYSICAL_ADDRESS Address; ACPI_STATUS Status; int TableStatus; if (strlen (Signature) != ACPI_NAME_SIZE) { AcpiLogError ( "Invalid table signature [%s]: must be exactly 4 characters\n", Signature); return (-1); } /* Table signatures are expected to be uppercase */ strcpy (LocalSignature, Signature); AcpiUtStrupr (LocalSignature); /* To be friendly, handle tables whose signatures do not match the name */ if (ACPI_COMPARE_NAME (LocalSignature, "FADT")) { strcpy (LocalSignature, ACPI_SIG_FADT); } else if (ACPI_COMPARE_NAME (LocalSignature, "MADT")) { strcpy (LocalSignature, ACPI_SIG_MADT); } /* Dump all instances of this signature (to handle multiple SSDTs) */ for (Instance = 0; Instance < AP_MAX_ACPI_FILES; Instance++) { Status = AcpiOsGetTableByName (LocalSignature, Instance, &Table, &Address); if (ACPI_FAILURE (Status)) { /* AE_LIMIT means that no more tables are available */ if (Status == AE_LIMIT) { return (0); } AcpiLogError ( "Could not get ACPI table with signature [%s], %s\n", LocalSignature, AcpiFormatException (Status)); return (-1); } TableStatus = ApDumpTableBuffer (Table, Instance, Address); ACPI_FREE (Table); if (TableStatus) { break; } } /* Something seriously bad happened if the loop terminates here */ return (-1); }
static int ApDoOptions ( int argc, char **argv) { int j; ACPI_STATUS Status; /* Command line options */ while ((j = AcpiGetopt (argc, argv, AP_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch (j) { /* * Global options */ case 'b': /* Dump all input tables to binary files */ Gbl_BinaryMode = TRUE; continue; case 'c': /* Dump customized tables */ Gbl_DumpCustomizedTables = TRUE; continue; case 'h': case '?': ApDisplayUsage (); return (1); case 'o': /* Redirect output to a single file */ if (ApOpenOutputFile (AcpiGbl_Optarg)) { return (-1); } continue; case 'r': /* Dump tables from specified RSDP */ Status = AcpiUtStrtoul64 (AcpiGbl_Optarg, 0, &Gbl_RsdpBase); if (ACPI_FAILURE (Status)) { AcpiLogError ("%s: Could not convert to a physical address\n", AcpiGbl_Optarg); return (-1); } continue; case 's': /* Print table summaries only */ Gbl_SummaryMode = TRUE; continue; case 'x': /* Do not use XSDT */ if (!AcpiGbl_DoNotUseXsdt) { AcpiGbl_DoNotUseXsdt = TRUE; } else { Gbl_DoNotDumpXsdt = TRUE; } continue; case 'v': /* Revision/version */ AcpiOsPrintf (ACPI_COMMON_SIGNON (AP_UTILITY_NAME)); return (1); case 'z': /* Verbose mode */ Gbl_VerboseMode = TRUE; AcpiLogError (ACPI_COMMON_SIGNON (AP_UTILITY_NAME)); continue; /* * Table options */ case 'a': /* Get table by physical address */ if (ApInsertAction (AcpiGbl_Optarg, AP_DUMP_TABLE_BY_ADDRESS)) { return (-1); } break; case 'f': /* Get table from a file */ if (ApInsertAction (AcpiGbl_Optarg, AP_DUMP_TABLE_BY_FILE)) { return (-1); } break; case 'n': /* Get table by input name (signature) */ if (ApInsertAction (AcpiGbl_Optarg, AP_DUMP_TABLE_BY_NAME)) { return (-1); } break; default: ApDisplayUsage (); return (-1); } /* If there are no actions, this means "get/dump all tables" */ if (CurrentAction == 0) { if (ApInsertAction (NULL, AP_DUMP_ALL_TABLES)) { return (-1); } } return (0); }
int ACPI_SYSTEM_XFACE acpi_main ( int argc, char *argv[]) #endif { int Status = 0; AP_DUMP_ACTION *Action; UINT32 FileSize; UINT32 i; ACPI_DEBUG_INITIALIZE (); /* For debug version only */ AcpiOsInitialize (); Gbl_OutputFile = ACPI_FILE_OUT; /* Process command line options */ Status = ApDoOptions (argc, argv); if (Status > 0) { return (0); } if (Status < 0) { return (Status); } /* Get/dump ACPI table(s) as requested */ for (i = 0; i < CurrentAction; i++) { Action = &ActionTable[i]; switch (Action->ToBeDone) { case AP_DUMP_ALL_TABLES: Status = ApDumpAllTables (); break; case AP_DUMP_TABLE_BY_ADDRESS: Status = ApDumpTableByAddress (Action->Argument); break; case AP_DUMP_TABLE_BY_NAME: Status = ApDumpTableByName (Action->Argument); break; case AP_DUMP_TABLE_BY_FILE: Status = ApDumpTableFromFile (Action->Argument); break; default: AcpiLogError ("Internal error, invalid action: 0x%X\n", Action->ToBeDone); return (-1); } if (Status) { return (Status); } } if (Gbl_OutputFilename) { if (Gbl_VerboseMode) { /* Summary for the output file */ FileSize = CmGetFileSize (Gbl_OutputFile); AcpiLogError ("Output file %s contains 0x%X (%u) bytes\n\n", Gbl_OutputFilename, FileSize, FileSize); } AcpiOsCloseFile (Gbl_OutputFile); } return (Status); }
ACPI_FILE AcpiOsOpenFile ( const char *Path, UINT8 Modes) { EFI_STATUS EfiStatus = EFI_SUCCESS; UINT64 OpenModes; EFI_FILE_HANDLE EfiFile = NULL; CHAR16 *Path16 = NULL; CHAR16 *Pos16; const char *Pos; INTN Count, i; if (!Path) { return (NULL); } /* Convert modes */ OpenModes = EFI_FILE_MODE_READ; if (Modes & ACPI_FILE_WRITING) { OpenModes |= (EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE); } /* Allocate path buffer */ Count = ACPI_STRLEN (Path); Path16 = ACPI_ALLOCATE_ZEROED ((Count + 1) * sizeof (CHAR16)); if (!Path16) { EfiStatus = EFI_BAD_BUFFER_SIZE; goto ErrorExit; } Pos = Path; Pos16 = Path16; while (*Pos == '/' || *Pos == '\\') { Pos++; Count--; } for (i = 0; i < Count; i++) { if (*Pos == '/') { *Pos16++ = '\\'; Pos++; } else { *Pos16++ = *Pos++; } } *Pos16 = '\0'; EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Open, 5, AcpiGbl_EfiCurrentVolume, &EfiFile, Path16, OpenModes, 0); if (EFI_ERROR (EfiStatus)) { AcpiLogError ("EFI_FILE_HANDLE->Open() failure.\n"); goto ErrorExit; } ErrorExit: if (Path16) { ACPI_FREE (Path16); } return ((ACPI_FILE) EfiFile); }