コード例 #1
0
ファイル: BootServices.c プロジェクト: jief666/clover
EFI_STATUS EFIAPI
OvrExitBootServices(
	IN EFI_HANDLE				ImageHandle,
	IN UINTN					MapKey
)
{
	EFI_STATUS					Status;
	UINTN					 	NewMapKey;
	
	PRINT("ExitBootServices called. Doing some more dumps ...\n");
	
	#if PRINT_DUMPS >= 1
	// Print ST
	PrintSystemTable(gST);
	
	// Print RT vars
	PrintRTVariables(&gOrgRS);
	#endif
	
	// Restore RT services if we should not log calls during runtime
	#if WORK_DURING_RUNTIME == 0
	RestoreRuntimeServices(gRT);
	#endif
	
	PRINT("->ExitBootServices(%p, 0x%x) ...\n", ImageHandle, MapKey);
	
	// Set flag to FALSE to stop some loggers from messing with memory
	InBootServices = FALSE;
	
	// Restore original OutputString
	#if CAPTURE_CONSOLE_OUTPUT >= 1
	gST->ConOut->OutputString = gOrgConOutOutputString;
	#endif
	
	// Notify loggers that boot services are over
	// Saving our log file can cause a vast amount of logging output on some firmwares, so do this after stopping loggers.
	LogOnExitBootServices();
	
	// Call original
	Status = gOrgBS.ExitBootServices(ImageHandle, MapKey);
	
	if (Status == EFI_SUCCESS) {
	
		PRINT("... ExitBootServices = %r\n", Status);
		
	} else {
		//
		// Error exiting boot services. Probably because
		// some of our loggers changed memory map state.
		// We'll just force exiting by obtaining new
		// MapKey and calling ExitBootServices again.
		//
		PRINT("... ExitBootServices = %r\n", Status);
		PRINT("Forcing ExitBootServices ...\n");
		
		Status = GetMemoryMapKey(&NewMapKey);
		if (Status == EFI_SUCCESS) {
			// we have latest mem map and NewMapKey
			// we'll try again ExitBootServices with NewMapKey
			Status = gOrgBS.ExitBootServices(ImageHandle, NewMapKey);
			PRINT("ExitBootServices: 2nd try = %r\n", Status);
		} else {
			PRINT("ERROR obtaining new map key: %r\n", Status);
			Status = EFI_INVALID_PARAMETER;
		}
	}
	
	return Status;
}