Пример #1
0
/**
  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;
}
Пример #2
0
/**
  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;
}
Пример #3
0
/**
  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;
}
Пример #4
0
/**
  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;
}