/** This function updates AML table checksum. It will search the ACPI table installed by ACPI_TABLE protocol. @param[in] Buffer A piece of AML code buffer pointer. @retval EFI_SUCCESS The table holds the AML buffer is found, and checksum is updated. @retval EFI_NOT_FOUND The table holds the AML buffer is not found. **/ EFI_STATUS SdtUpdateAmlChecksum ( IN VOID *Buffer ) { EFI_ACPI_TABLE_LIST *CurrentTableList; CurrentTableList = FindTableByBuffer (Buffer); if (CurrentTableList == NULL) { return EFI_NOT_FOUND; } AcpiPlatformChecksum ( (VOID *)CurrentTableList->Table, CurrentTableList->Table->Length, OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum) ); return EFI_SUCCESS; }
/** Entrypoint of Acpi Platform driver. @param ImageHandle @param SystemTable @return EFI_SUCCESS @return EFI_LOAD_ERROR @return EFI_OUT_OF_RESOURCES **/ EFI_STATUS EFIAPI AcpiPlatformEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; #ifdef VBOX VOID *VBoxTables[10]; #else EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; #endif INTN Instance; EFI_ACPI_COMMON_HEADER *CurrentTable; UINTN TableHandle; #ifndef VBOX UINT32 FvStatus; #endif UINTN TableSize; UINTN Size; Instance = 0; CurrentTable = NULL; TableHandle = 0; // // Find the AcpiTable protocol // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable); if (EFI_ERROR (Status)) { return EFI_ABORTED; } #ifdef VBOX // // VBOX already has tables prepared in memory - just reuse them. // FillSysTablesInfo(VBoxTables, sizeof(VBoxTables)/sizeof(VBoxTables[0])); #else // // // Locate the firmware volume protocol // Status = LocateFvInstanceWithTables (&FwVol); if (EFI_ERROR (Status)) { return EFI_ABORTED; } #endif // // Read tables from the storage file. // while (Status == EFI_SUCCESS) { #ifdef VBOX CurrentTable = (EFI_ACPI_COMMON_HEADER *)VBoxTables[Instance]; Status = (CurrentTable == NULL) ? EFI_NOT_FOUND : EFI_SUCCESS; if (CurrentTable) { Size = CurrentTable->Length; DEBUG((EFI_D_ERROR, "adding %p %d\n", CurrentTable, Size)); } else Size = 0; // Just to shut up the compiler. #else Status = FwVol->ReadSection ( FwVol, (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile), EFI_SECTION_RAW, Instance, (VOID**) &CurrentTable, &Size, &FvStatus ); #endif if (!EFI_ERROR(Status)) { // // Add the table // TableHandle = 0; TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length; #ifdef VBOX DEBUG((DEBUG_INFO, "Size:%d, TableSize:%d\n", Size, TableSize)); #endif ASSERT (Size >= TableSize); // // Checksum ACPI table // AcpiPlatformChecksum ((UINT8*)CurrentTable, TableSize); // // Install ACPI table // Status = AcpiTable->InstallAcpiTable ( AcpiTable, CurrentTable, TableSize, &TableHandle ); #ifndef VBOX /* In case we're reading ACPI tables from memory we haven't allocated this memory, so it isn't required to free it */ // // Free memory allocated by ReadSection // gBS->FreePool (CurrentTable); if (EFI_ERROR(Status)) { return EFI_ABORTED; } #endif // // Increment the instance // Instance++; CurrentTable = NULL; } } return EFI_SUCCESS; }
/** Entrypoint of Acpi Platform driver. @param ImageHandle @param SystemTable @return EFI_SUCCESS @return EFI_LOAD_ERROR @return EFI_OUT_OF_RESOURCES **/ EFI_STATUS EFIAPI AcpiPlatformEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; INTN Instance; EFI_ACPI_COMMON_HEADER *CurrentTable; UINTN TableHandle; UINT32 FvStatus; UINTN TableSize; UINTN Size; Instance = 0; CurrentTable = NULL; TableHandle = 0; // // Find the AcpiTable protocol // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable); if (EFI_ERROR (Status)) { return EFI_ABORTED; } // // Locate the firmware volume protocol // Status = LocateFvInstanceWithTables (&FwVol); if (EFI_ERROR (Status)) { return EFI_ABORTED; } // // Read tables from the storage file. // while (Status == EFI_SUCCESS) { Status = FwVol->ReadSection ( FwVol, (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile), EFI_SECTION_RAW, Instance, (VOID**) &CurrentTable, &Size, &FvStatus ); if (!EFI_ERROR(Status)) { // // Add the table // TableHandle = 0; TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length; ASSERT (Size >= TableSize); // // Checksum ACPI table // AcpiPlatformChecksum ((UINT8*)CurrentTable, TableSize); // // Install ACPI table // Status = AcpiTable->InstallAcpiTable ( AcpiTable, CurrentTable, TableSize, &TableHandle ); // // Free memory allocated by ReadSection // gBS->FreePool (CurrentTable); if (EFI_ERROR(Status)) { return EFI_ABORTED; } // // Increment the instance // Instance++; CurrentTable = NULL; } } // // The driver does not require to be kept loaded. // return EFI_REQUEST_UNLOAD_IMAGE; }
/** Entrypoint of Acpi Platform driver. @param ImageHandle @param SystemTable @return EFI_SUCCESS @return EFI_LOAD_ERROR @return EFI_OUT_OF_RESOURCES **/ EFI_STATUS EFIAPI AcpiPlatformEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; // INTN Instance; // EFI_ACPI_COMMON_HEADER *CurrentTable; EFI_ACPI_COMMON_HEADER *oldDSDT; UINTN TableHandle; UINTN TableSize; // UINTN Size; #if READTABLES UINTN Index; CHAR16* FileName; #if LIP EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; #endif VOID *FileBuffer; // VOID** TmpHandler; UINT64 FileSize; UINTN BufferSize; // UINTN Key; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume; EFI_FILE_INFO *Info; EFI_FILE_HANDLE Root = NULL; EFI_FILE_HANDLE ThisFile = NULL; #endif EFI_PHYSICAL_ADDRESS *Acpi20; EFI_PEI_HOB_POINTERS GuidHob; EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp; // EFI_ACPI_DESCRIPTION_HEADER *Rsdt, *Xsdt; // EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt; EFI_ACPI_DESCRIPTION_HEADER *Table; SIGNAT Signature; // EFI_ACPI_TABLE_INSTANCE *AcpiInstance; Msg = NULL; Status = gBS->LocateProtocol(&gMsgLogProtocolGuid, NULL, (VOID **) &Msg); if (!EFI_ERROR(Status) && (Msg != NULL)) { msgCursor = Msg->Cursor; BootLog("MsgLog Protocol installed in AcpiPlatform\n"); } // // Find the AcpiTable protocol // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable); if (EFI_ERROR (Status)) { return EFI_ABORTED; } #if DEBUG_ACPI AcpiInstance = EFI_ACPI_TABLE_INSTANCE_FROM_THIS(AcpiTable); DBG(L"Rsdp1 %x\n", AcpiInstance->Rsdp1); DBG(L"Rsdp3 %x\n", AcpiInstance->Rsdp3); DBG(L"Rsdt1 %x\n", AcpiInstance->Rsdt1); DBG(L"Rsdt3 %x\n", AcpiInstance->Rsdt3); DBG(L"Xsdt %x\n", AcpiInstance->Xsdt); DBG(L"Fadt1 %x\n", AcpiInstance->Fadt1); DBG(L"Fadt3 %x\n", AcpiInstance->Fadt3); #endif // Instance = 0; // CurrentTable = NULL; TableHandle = 0; GuidHob.Raw = GetFirstGuidHob (&gEfiAcpiTableGuid); if (GuidHob.Raw == NULL) { GuidHob.Raw = GetFirstGuidHob (&gEfiAcpi10TableGuid); if (GuidHob.Raw == NULL) { return EFI_ABORTED; } //Slice: TODO if we found only Acpi1.0 we need to convert it to Acpi2.0 // like I did in Chameleon } Acpi20 = GET_GUID_HOB_DATA (GuidHob.Guid); if (Acpi20 == NULL) { return EFI_ABORTED; } Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)*Acpi20; DBG(L"Rsdp @ %x\n", (UINTN)Rsdp); DBG(L"Rsdt @ %x\n", (UINTN)(Rsdp->RsdtAddress)); DBG(L"Xsdt @ %x\n", (UINTN)(Rsdp->XsdtAddress)); InstallLegacyTables(AcpiTable, Rsdp); // DBG(L"LegacyTables installed\n"); oldDSDT = (EFI_ACPI_COMMON_HEADER*)(UINTN)Fadt->Dsdt; DBG(L"Fadt @ %x\n", (UINTN)Fadt); DBG(L"oldDSDT @ %x\n", (UINTN)oldDSDT); #if READTABLES #if LIP // Looking for a volume from what we boot /* TODO - look for a volume we want to boot System it is possible if we fix in BdsBoot.c gRT->SetVariable ( L"BootCurrent", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof (UINT16), &Option->BootCurrent ); gRT->GetVariable ( L"BootNext", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, 0, &BootNext ); and extract DevicePath from BootNext - first available :( In Gui.efi we can repeat this patch with DSDT.aml loaded from another place */ Status = gBS->HandleProtocol ( ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID*)&LoadedImage ); if (EFI_ERROR (Status)) { return EFI_ABORTED; } Status = gBS->HandleProtocol ( LoadedImage->DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID *) &Volume ); if (EFI_ERROR (Status)) { return EFI_ABORTED; } // DBG(L"Volume found\n"); // // Open the root directory of the volume // if (!EFI_ERROR (Status)) { Status = Volume->OpenVolume (Volume, &Root); } #else //Multiple FS protocols EFI_HANDLE *mFs = NULL; UINTN mFsCount = 0; // mFsInfo[] array entries must match mFs[] handles EFI_FILE_SYSTEM_INFO **mFsInfo = NULL; gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &mFsCount, &mFs); mFsInfo = AllocateZeroPool (mFsCount * sizeof (EFI_FILE_SYSTEM_INFO *)); if (mFsInfo == NULL) { // If we can't do this then we can't support file system entries mFsCount = 0; } else { // Loop through all the file system structures and cache the file system info data for (Index =0; Index < mFsCount; Index++) { Status = gBS->HandleProtocol (mFs[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Volume); if (!EFI_ERROR (Status)) { Status = Volume->OpenVolume (Volume, &Root); if (!EFI_ERROR (Status)) { // Get information about the volume /* Size = 0; Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, mFsInfo[Index]); if (Status == EFI_BUFFER_TOO_SMALL) { mFsInfo[Index] = AllocatePool (Size); Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, mFsInfo[Index]); } */ // Root->Close (Root); break; //I will stop at first volume //TODO try to find DSDT in all volumes } } } } #endif FileName = AllocateZeroPool(32); //Should be enough // // Read tables from the first volume. // for (Index=0; Index<NUM_TABLES; Index++) { StrCpyS(FileName, 32, ACPInames[Index]); // DBG(L"File probe %s\n", FileName); Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0); if (EFI_ERROR (Status)) { continue; } /* Get right size we need to allocate */ Status = ThisFile->GetInfo ( ThisFile, &gEfiFileInfoGuid, &BufferSize, Info ); if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) { continue; } DBG(L"Buffer size %d\n", BufferSize); // DBG(L"GetInfo success!\n"); Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info); if (EFI_ERROR (Status)) { // DBG(L"No pool!\n"); continue; } Status = ThisFile->GetInfo ( ThisFile, &gEfiFileInfoGuid, &BufferSize, Info ); FileSize = Info->FileSize; // DBG(L"FileSize = %d!\n", FileSize); gBS->FreePool (Info); //Slice - this is the problem. // FileBuffer = AllocatePool(FileSize); Status = gBS->AllocatePool (EfiBootServicesData, FileSize, (VOID **) &FileBuffer); if (EFI_ERROR (Status)) { // DBG(L"No pool for FileBuffer size %d!\n", FileSize); continue; } /* Status = gBS->AllocatePages ( AllocateMaxAddress, EfiACPIMemoryNVS, EFI_SIZE_TO_PAGES(FileSize), FileBuffer ); if (EFI_ERROR (Status)) { // DBG(L"No pool for FileBuffer size %d!\n", FileSize); continue; } */ //should use ACPI memory // Status=gBS->AllocatePages(AllocateMaxAddress, // EfiACPIReclaimMemory,RoundPage(FileSize)/EFI_PAGE_SIZE, FileBuffer); DBG(L"FileBuffer @ %x\n", (UINTN)FileBuffer); Status = ThisFile->Read (ThisFile, &FileSize, FileBuffer); //(VOID**)& // DBG(L"FileRead status=%x\n", Status); if (!EFI_ERROR(Status)) { // // Add the table // // TableHandle = 0; if (ThisFile != NULL) { ThisFile->Close (ThisFile); //close file before use buffer?! Flush?! } // DBG(L"FileRead success: %c%c%c%c\n", // ((CHAR8*)FileBuffer)[0], ((CHAR8*)FileBuffer)[1], ((CHAR8*)FileBuffer)[2], ((CHAR8*)FileBuffer)[3]); TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) FileBuffer)->Length; //ASSERT (BufferSize >= TableSize); DBG(L"Table size=%d\n", TableSize); if (FileSize < TableSize) { //Data incorrect. What TODO? Quick fix // ((EFI_ACPI_DESCRIPTION_HEADER *) FileBuffer)->Length = FileSize; // TableSize = FileSize; DBG(L"Table size > file size :(\n"); continue; //do nothing with broken table } // // Checksum ACPI table // AcpiPlatformChecksum ((UINT8*)FileBuffer, TableSize); if ((Index==0) && oldDSDT) { //DSDT always at index 0 if (((EFI_ACPI_DESCRIPTION_HEADER *) oldDSDT)->Length > TableSize) { CopyMem(oldDSDT, FileBuffer, TableSize); DBG(L"New DSDT copied to old place\n"); } } // // Install ACPI table // //TmpHandler = &FileBuffer; Status = AcpiTable->InstallAcpiTable ( AcpiTable, FileBuffer, TableSize, &TableHandle ); DBG(L"Table install status=%x\n", Status); if (EFI_ERROR(Status)) { continue; } // DBG(L"Table installed #%d\n", Index); // // Increment the instance // // Instance++; //for a what? FileBuffer = NULL; } else if (oldDSDT && (Index==0)) { //if new DSDT not found then install legacy one Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(Fadt->Dsdt)); TableSize = Table->Length; Signature.Sign = Table->Signature; DBG(L"Install legacy table: %c%c%c%c\n", Signature.ASign[0], Signature.ASign[1], Signature.ASign[2], Signature.ASign[3]); Status = AcpiTable->InstallAcpiTable ( AcpiTable, Table, TableSize, &TableHandle ); } } if (Root != NULL) { Root->Close (Root); } #else //just install legacy tables if (oldDSDT) { //if new DSDT not found then install legacy one Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(Fadt->Dsdt)); TableSize = Table->Length; Signature.Sign = Table->Signature; DBG(L"Install legacy table: %c%c%c%c\n", Signature.ASign[0], Signature.ASign[1], Signature.ASign[2], Signature.ASign[3]); /*Status = */AcpiTable->InstallAcpiTable ( AcpiTable, Table, TableSize, &TableHandle ); } #endif #if DEBUG_ACPI==2 gBS->Stall(5000000); #endif return EFI_SUCCESS; }