diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 1f15582cca..6c87d1c746 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -70,21 +70,21 @@ SysCall/SupportedProtocols.h SysCall/SupportedProtocols.c -[Sources.IA32] - SysCall/IA32/InitializeMsr.c - SysCall/IA32/CoreBootServices.nasm - -[Sources.X64] - SysCall/X64/InitializeMsr.c - SysCall/X64/CoreBootServices.nasm - -[Sources.ARM] - SysCall/ARM/InitializeMsr.c - SysCall/ARM/CoreBootServices.S - -[Sources.AARCH64] - SysCall/AARCH64/InitializeMsr.c - SysCall/AARCH64/CoreBootServices.S +[Sources.IA32] + SysCall/IA32/InitializeMsr.c + SysCall/IA32/CoreBootServices.nasm + +[Sources.X64] + SysCall/X64/InitializeMsr.c + SysCall/X64/CoreBootServices.nasm + +[Sources.ARM] + SysCall/ARM/InitializeMsr.c + SysCall/ARM/CoreBootServices.S + +[Sources.AARCH64] + SysCall/AARCH64/InitializeMsr.c + SysCall/AARCH64/CoreBootServices.S [Packages] MdePkg/MdePkg.dec @@ -93,7 +93,7 @@ OvmfPkg/OvmfPkg.dec ArmPkg/ArmPkg.dec ArmVirtPkg/ArmVirtPkg.dec - + [LibraryClasses] BaseMemoryLib CacheMaintenanceLib diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S b/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S index b3cc3d7c72..7ed039d821 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S +++ b/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S @@ -1,32 +1,32 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause -//------------------------------------------------------------------------------ - -#include - -.extern ASM_PFX(Ring3Call) - -//------------------------------------------------------------------------------ -// EFI_STATUS -// EFIAPI -// SysCall ( -// IN UINT8 Type, -// ... -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(SysCall) - svc #0 - ret - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// Ring3EntryPoint ( -// IN RING3_CALL_DATA *Data -// ); -// -// (x0) Data -//------------------------------------------------------------------------------ -ASM_FUNC(Ring3EntryPoint) - b ASM_PFX(Ring3Call) +//------------------------------------------------------------------------------ +// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +//------------------------------------------------------------------------------ + +#include + +.extern ASM_PFX(Ring3Call) + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// SysCall ( +// IN UINT8 Type, +// ... +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(SysCall) + svc #0 + ret + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// Ring3EntryPoint ( +// IN RING3_CALL_DATA *Data +// ); +// +// (x0) Data +//------------------------------------------------------------------------------ +ASM_FUNC(Ring3EntryPoint) + b ASM_PFX(Ring3Call) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S b/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S index 25fcc31ab2..2f0495f31f 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S +++ b/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S @@ -1,32 +1,32 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause -//------------------------------------------------------------------------------ - -#include - -.extern ASM_PFX(Ring3Call) - -//------------------------------------------------------------------------------ -// EFI_STATUS -// EFIAPI -// SysCall ( -// IN UINT8 Type, -// ... -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(SysCall) - svc #0 - bx LR - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// Ring3EntryPoint ( -// IN RING3_CALL_DATA *Data -// ); -// -// (r0) Data -//------------------------------------------------------------------------------ -ASM_FUNC(Ring3EntryPoint) - b ASM_PFX(Ring3Call) +//------------------------------------------------------------------------------ +// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +//------------------------------------------------------------------------------ + +#include + +.extern ASM_PFX(Ring3Call) + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// SysCall ( +// IN UINT8 Type, +// ... +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(SysCall) + svc #0 + bx LR + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// Ring3EntryPoint ( +// IN RING3_CALL_DATA *Data +// ); +// +// (r0) Data +//------------------------------------------------------------------------------ +ASM_FUNC(Ring3EntryPoint) + b ASM_PFX(Ring3Call) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index 492b2cd372..3afb8f37e4 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -1,265 +1,265 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include -#include -#include -#include -#include - -#include "Ring3.h" - -EFI_BOOT_SERVICES mBootServices = { - { - EFI_BOOT_SERVICES_SIGNATURE, // Signature - EFI_BOOT_SERVICES_REVISION, // Revision - sizeof (EFI_BOOT_SERVICES), // HeaderSize - 0, // CRC32 - 0 // Reserved - }, - (EFI_RAISE_TPL)Ring3RaiseTpl, // RaiseTPL - (EFI_RESTORE_TPL)Ring3RestoreTpl, // RestoreTPL - (EFI_ALLOCATE_PAGES)Ring3AllocatePages, // AllocatePages - (EFI_FREE_PAGES)Ring3FreePages, // FreePages - (EFI_GET_MEMORY_MAP)Ring3GetMemoryMap, // GetMemoryMap - (EFI_ALLOCATE_POOL)CoreAllocatePool, // AllocatePool - (EFI_FREE_POOL)CoreFreePool, // FreePool - (EFI_CREATE_EVENT)Ring3CreateEvent, // CreateEvent - (EFI_SET_TIMER)Ring3SetTimer, // SetTimer - (EFI_WAIT_FOR_EVENT)Ring3WaitForEvent, // WaitForEvent - (EFI_SIGNAL_EVENT)Ring3SignalEvent, // SignalEvent - (EFI_CLOSE_EVENT)Ring3CloseEvent, // CloseEvent - (EFI_CHECK_EVENT)Ring3CheckEvent, // CheckEvent - (EFI_INSTALL_PROTOCOL_INTERFACE)Ring3InstallProtocolInterface, // InstallProtocolInterface - (EFI_REINSTALL_PROTOCOL_INTERFACE)Ring3ReinstallProtocolInterface, // ReinstallProtocolInterface - (EFI_UNINSTALL_PROTOCOL_INTERFACE)Ring3UninstallProtocolInterface, // UninstallProtocolInterface - (EFI_HANDLE_PROTOCOL)Ring3HandleProtocol, // HandleProtocol - (VOID *)NULL, // Reserved - (EFI_REGISTER_PROTOCOL_NOTIFY)Ring3RegisterProtocolNotify, // RegisterProtocolNotify - (EFI_LOCATE_HANDLE)Ring3LocateHandle, // LocateHandle - (EFI_LOCATE_DEVICE_PATH)Ring3LocateDevicePath, // LocateDevicePath - (EFI_INSTALL_CONFIGURATION_TABLE)Ring3InstallConfigurationTable, // InstallConfigurationTable - (EFI_IMAGE_LOAD)Ring3LoadImage, // LoadImage - (EFI_IMAGE_START)Ring3StartImage, // StartImage - (EFI_EXIT)Ring3Exit, // Exit - (EFI_IMAGE_UNLOAD)Ring3UnloadImage, // UnloadImage - (EFI_EXIT_BOOT_SERVICES)Ring3ExitBootServices, // ExitBootServices - (EFI_GET_NEXT_MONOTONIC_COUNT)Ring3GetNextMonotonicCount, // GetNextMonotonicCount - (EFI_STALL)Ring3Stall, // Stall - (EFI_SET_WATCHDOG_TIMER)Ring3SetWatchdogTimer, // SetWatchdogTimer - (EFI_CONNECT_CONTROLLER)Ring3ConnectController, // ConnectController - (EFI_DISCONNECT_CONTROLLER)Ring3DisconnectController, // DisconnectController - (EFI_OPEN_PROTOCOL)Ring3OpenProtocol, // OpenProtocol - (EFI_CLOSE_PROTOCOL)Ring3CloseProtocol, // CloseProtocol - (EFI_OPEN_PROTOCOL_INFORMATION)Ring3OpenProtocolInformation, // OpenProtocolInformation - (EFI_PROTOCOLS_PER_HANDLE)Ring3ProtocolsPerHandle, // ProtocolsPerHandle - (EFI_LOCATE_HANDLE_BUFFER)Ring3LocateHandleBuffer, // LocateHandleBuffer - (EFI_LOCATE_PROTOCOL)Ring3LocateProtocol, // LocateProtocol - (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)Ring3InstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces - (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)Ring3UninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces - (EFI_CALCULATE_CRC32)Ring3CalculateCrc32, // CalculateCrc32 - (EFI_COPY_MEM)CopyMem, // CopyMem - (EFI_SET_MEM)SetMem, // SetMem - (EFI_CREATE_EVENT_EX)Ring3CreateEventEx, // CreateEventEx -}; - -EFI_RUNTIME_SERVICES mRuntimeServices = { - { - EFI_RUNTIME_SERVICES_SIGNATURE, // Signature - EFI_RUNTIME_SERVICES_REVISION, // Revision - sizeof (EFI_RUNTIME_SERVICES), // HeaderSize - 0, // CRC32 - 0 // Reserved - }, - (EFI_GET_TIME)Ring3GetTime, // GetTime - (EFI_SET_TIME)Ring3SetTime, // SetTime - (EFI_GET_WAKEUP_TIME)Ring3GetWakeupTime, // GetWakeupTime - (EFI_SET_WAKEUP_TIME)Ring3SetWakeupTime, // SetWakeupTime - (EFI_SET_VIRTUAL_ADDRESS_MAP)Ring3SetVirtualAddressMap, // SetVirtualAddressMap - (EFI_CONVERT_POINTER)Ring3ConvertPointer, // ConvertPointer - (EFI_GET_VARIABLE)Ring3GetVariable, // GetVariable - (EFI_GET_NEXT_VARIABLE_NAME)Ring3GetNextVariableName, // GetNextVariableName - (EFI_SET_VARIABLE)Ring3SetVariable, // SetVariable - (EFI_GET_NEXT_HIGH_MONO_COUNT)Ring3GetNextHighMonotonicCount, // GetNextHighMonotonicCount - (EFI_RESET_SYSTEM)Ring3ResetSystem, // ResetSystem - (EFI_UPDATE_CAPSULE)Ring3UpdateCapsule, // UpdateCapsule - (EFI_QUERY_CAPSULE_CAPABILITIES)Ring3QueryCapsuleCapabilities, // QueryCapsuleCapabilities - (EFI_QUERY_VARIABLE_INFO)Ring3QueryVariableInfo // QueryVariableInfo -}; - -VOID -EFIAPI -Ring3EntryPoint ( - IN RING3_CALL_DATA *Data - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_0)( - VOID - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_1)( - IN UINTN Argument1 - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_2)( - IN UINTN Argument1, - IN UINTN Argument2 - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_3)( - IN UINTN Argument1, - IN UINTN Argument2, - IN UINTN Argument3 - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_4)( - IN UINTN Argument1, - IN UINTN Argument2, - IN UINTN Argument3, - IN UINTN Argument4 - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_5)( - IN UINTN Argument1, - IN UINTN Argument2, - IN UINTN Argument3, - IN UINTN Argument4, - IN UINTN Argument5 - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_6)( - IN UINTN Argument1, - IN UINTN Argument2, - IN UINTN Argument3, - IN UINTN Argument4, - IN UINTN Argument5, - IN UINTN Argument6 - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_7)( - IN UINTN Argument1, - IN UINTN Argument2, - IN UINTN Argument3, - IN UINTN Argument4, - IN UINTN Argument5, - IN UINTN Argument6, - IN UINTN Argument7 - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_8)( - IN UINTN Argument1, - IN UINTN Argument2, - IN UINTN Argument3, - IN UINTN Argument4, - IN UINTN Argument5, - IN UINTN Argument6, - IN UINTN Argument7, - IN UINTN Argument8 - ); - -VOID -EFIAPI -Ring3Call ( - IN RING3_CALL_DATA *Data - ) -{ - EFI_STATUS Status; - FUNCTION_0 Function0; - FUNCTION_1 Function1; - FUNCTION_2 Function2; - FUNCTION_3 Function3; - FUNCTION_4 Function4; - FUNCTION_5 Function5; - FUNCTION_6 Function6; - FUNCTION_7 Function7; - FUNCTION_8 Function8; - - switch (Data->NumberOfArguments) { - case 0: - Function0 = (FUNCTION_0)Data->EntryPoint; - Status = Function0 (); - break; - case 1: - Function1 = (FUNCTION_1)Data->EntryPoint; - Status = Function1 (Data->Arguments[0]); - break; - case 2: - Function2 = (FUNCTION_2)Data->EntryPoint; - Status = Function2 (Data->Arguments[0], Data->Arguments[1]); - break; - case 3: - Function3 = (FUNCTION_3)Data->EntryPoint; - Status = Function3 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2]); - break; - case 4: - Function4 = (FUNCTION_4)Data->EntryPoint; - Status = Function4 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3]); - break; - case 5: - Function5 = (FUNCTION_5)Data->EntryPoint; - Status = Function5 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4]); - break; - case 6: - Function6 = (FUNCTION_6)Data->EntryPoint; - Status = Function6 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4], Data->Arguments[5]); - break; - case 7: - Function7 = (FUNCTION_7)Data->EntryPoint; - Status = Function7 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4], Data->Arguments[5], Data->Arguments[6]); - break; - case 8: - Function8 = (FUNCTION_8)Data->EntryPoint; - Status = Function8 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4], Data->Arguments[5], Data->Arguments[6], Data->Arguments[7]); - break; - default: - Status = EFI_UNSUPPORTED; - break; - } - - SysCall (SysCallReturnToCore, Status); -} - -EFI_STATUS -EFIAPI -Ring3Initialization ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - RING3_DATA *Ring3Data; - - Ring3Data = (RING3_DATA *)SystemTable; - - Ring3Data->EntryPoint = (VOID *)Ring3EntryPoint; - Ring3Data->BootServices = &mBootServices; - Ring3Data->RuntimeServices = &mRuntimeServices; - - gBS = &mBootServices; - gRT = &mRuntimeServices; - - CoreInitializePool (); - - return EFI_SUCCESS; -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include +#include +#include +#include +#include + +#include "Ring3.h" + +EFI_BOOT_SERVICES mBootServices = { + { + EFI_BOOT_SERVICES_SIGNATURE, // Signature + EFI_BOOT_SERVICES_REVISION, // Revision + sizeof (EFI_BOOT_SERVICES), // HeaderSize + 0, // CRC32 + 0 // Reserved + }, + (EFI_RAISE_TPL)Ring3RaiseTpl, // RaiseTPL + (EFI_RESTORE_TPL)Ring3RestoreTpl, // RestoreTPL + (EFI_ALLOCATE_PAGES)Ring3AllocatePages, // AllocatePages + (EFI_FREE_PAGES)Ring3FreePages, // FreePages + (EFI_GET_MEMORY_MAP)Ring3GetMemoryMap, // GetMemoryMap + (EFI_ALLOCATE_POOL)CoreAllocatePool, // AllocatePool + (EFI_FREE_POOL)CoreFreePool, // FreePool + (EFI_CREATE_EVENT)Ring3CreateEvent, // CreateEvent + (EFI_SET_TIMER)Ring3SetTimer, // SetTimer + (EFI_WAIT_FOR_EVENT)Ring3WaitForEvent, // WaitForEvent + (EFI_SIGNAL_EVENT)Ring3SignalEvent, // SignalEvent + (EFI_CLOSE_EVENT)Ring3CloseEvent, // CloseEvent + (EFI_CHECK_EVENT)Ring3CheckEvent, // CheckEvent + (EFI_INSTALL_PROTOCOL_INTERFACE)Ring3InstallProtocolInterface, // InstallProtocolInterface + (EFI_REINSTALL_PROTOCOL_INTERFACE)Ring3ReinstallProtocolInterface, // ReinstallProtocolInterface + (EFI_UNINSTALL_PROTOCOL_INTERFACE)Ring3UninstallProtocolInterface, // UninstallProtocolInterface + (EFI_HANDLE_PROTOCOL)Ring3HandleProtocol, // HandleProtocol + (VOID *)NULL, // Reserved + (EFI_REGISTER_PROTOCOL_NOTIFY)Ring3RegisterProtocolNotify, // RegisterProtocolNotify + (EFI_LOCATE_HANDLE)Ring3LocateHandle, // LocateHandle + (EFI_LOCATE_DEVICE_PATH)Ring3LocateDevicePath, // LocateDevicePath + (EFI_INSTALL_CONFIGURATION_TABLE)Ring3InstallConfigurationTable, // InstallConfigurationTable + (EFI_IMAGE_LOAD)Ring3LoadImage, // LoadImage + (EFI_IMAGE_START)Ring3StartImage, // StartImage + (EFI_EXIT)Ring3Exit, // Exit + (EFI_IMAGE_UNLOAD)Ring3UnloadImage, // UnloadImage + (EFI_EXIT_BOOT_SERVICES)Ring3ExitBootServices, // ExitBootServices + (EFI_GET_NEXT_MONOTONIC_COUNT)Ring3GetNextMonotonicCount, // GetNextMonotonicCount + (EFI_STALL)Ring3Stall, // Stall + (EFI_SET_WATCHDOG_TIMER)Ring3SetWatchdogTimer, // SetWatchdogTimer + (EFI_CONNECT_CONTROLLER)Ring3ConnectController, // ConnectController + (EFI_DISCONNECT_CONTROLLER)Ring3DisconnectController, // DisconnectController + (EFI_OPEN_PROTOCOL)Ring3OpenProtocol, // OpenProtocol + (EFI_CLOSE_PROTOCOL)Ring3CloseProtocol, // CloseProtocol + (EFI_OPEN_PROTOCOL_INFORMATION)Ring3OpenProtocolInformation, // OpenProtocolInformation + (EFI_PROTOCOLS_PER_HANDLE)Ring3ProtocolsPerHandle, // ProtocolsPerHandle + (EFI_LOCATE_HANDLE_BUFFER)Ring3LocateHandleBuffer, // LocateHandleBuffer + (EFI_LOCATE_PROTOCOL)Ring3LocateProtocol, // LocateProtocol + (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)Ring3InstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces + (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)Ring3UninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces + (EFI_CALCULATE_CRC32)Ring3CalculateCrc32, // CalculateCrc32 + (EFI_COPY_MEM)CopyMem, // CopyMem + (EFI_SET_MEM)SetMem, // SetMem + (EFI_CREATE_EVENT_EX)Ring3CreateEventEx, // CreateEventEx +}; + +EFI_RUNTIME_SERVICES mRuntimeServices = { + { + EFI_RUNTIME_SERVICES_SIGNATURE, // Signature + EFI_RUNTIME_SERVICES_REVISION, // Revision + sizeof (EFI_RUNTIME_SERVICES), // HeaderSize + 0, // CRC32 + 0 // Reserved + }, + (EFI_GET_TIME)Ring3GetTime, // GetTime + (EFI_SET_TIME)Ring3SetTime, // SetTime + (EFI_GET_WAKEUP_TIME)Ring3GetWakeupTime, // GetWakeupTime + (EFI_SET_WAKEUP_TIME)Ring3SetWakeupTime, // SetWakeupTime + (EFI_SET_VIRTUAL_ADDRESS_MAP)Ring3SetVirtualAddressMap, // SetVirtualAddressMap + (EFI_CONVERT_POINTER)Ring3ConvertPointer, // ConvertPointer + (EFI_GET_VARIABLE)Ring3GetVariable, // GetVariable + (EFI_GET_NEXT_VARIABLE_NAME)Ring3GetNextVariableName, // GetNextVariableName + (EFI_SET_VARIABLE)Ring3SetVariable, // SetVariable + (EFI_GET_NEXT_HIGH_MONO_COUNT)Ring3GetNextHighMonotonicCount, // GetNextHighMonotonicCount + (EFI_RESET_SYSTEM)Ring3ResetSystem, // ResetSystem + (EFI_UPDATE_CAPSULE)Ring3UpdateCapsule, // UpdateCapsule + (EFI_QUERY_CAPSULE_CAPABILITIES)Ring3QueryCapsuleCapabilities, // QueryCapsuleCapabilities + (EFI_QUERY_VARIABLE_INFO)Ring3QueryVariableInfo // QueryVariableInfo +}; + +VOID +EFIAPI +Ring3EntryPoint ( + IN RING3_CALL_DATA *Data + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_0)( + VOID + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_1)( + IN UINTN Argument1 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_2)( + IN UINTN Argument1, + IN UINTN Argument2 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_3)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_4)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3, + IN UINTN Argument4 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_5)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3, + IN UINTN Argument4, + IN UINTN Argument5 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_6)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3, + IN UINTN Argument4, + IN UINTN Argument5, + IN UINTN Argument6 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_7)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3, + IN UINTN Argument4, + IN UINTN Argument5, + IN UINTN Argument6, + IN UINTN Argument7 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_8)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3, + IN UINTN Argument4, + IN UINTN Argument5, + IN UINTN Argument6, + IN UINTN Argument7, + IN UINTN Argument8 + ); + +VOID +EFIAPI +Ring3Call ( + IN RING3_CALL_DATA *Data + ) +{ + EFI_STATUS Status; + FUNCTION_0 Function0; + FUNCTION_1 Function1; + FUNCTION_2 Function2; + FUNCTION_3 Function3; + FUNCTION_4 Function4; + FUNCTION_5 Function5; + FUNCTION_6 Function6; + FUNCTION_7 Function7; + FUNCTION_8 Function8; + + switch (Data->NumberOfArguments) { + case 0: + Function0 = (FUNCTION_0)Data->EntryPoint; + Status = Function0 (); + break; + case 1: + Function1 = (FUNCTION_1)Data->EntryPoint; + Status = Function1 (Data->Arguments[0]); + break; + case 2: + Function2 = (FUNCTION_2)Data->EntryPoint; + Status = Function2 (Data->Arguments[0], Data->Arguments[1]); + break; + case 3: + Function3 = (FUNCTION_3)Data->EntryPoint; + Status = Function3 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2]); + break; + case 4: + Function4 = (FUNCTION_4)Data->EntryPoint; + Status = Function4 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3]); + break; + case 5: + Function5 = (FUNCTION_5)Data->EntryPoint; + Status = Function5 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4]); + break; + case 6: + Function6 = (FUNCTION_6)Data->EntryPoint; + Status = Function6 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4], Data->Arguments[5]); + break; + case 7: + Function7 = (FUNCTION_7)Data->EntryPoint; + Status = Function7 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4], Data->Arguments[5], Data->Arguments[6]); + break; + case 8: + Function8 = (FUNCTION_8)Data->EntryPoint; + Status = Function8 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4], Data->Arguments[5], Data->Arguments[6], Data->Arguments[7]); + break; + default: + Status = EFI_UNSUPPORTED; + break; + } + + SysCall (SysCallReturnToCore, Status); +} + +EFI_STATUS +EFIAPI +Ring3Initialization ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + RING3_DATA *Ring3Data; + + Ring3Data = (RING3_DATA *)SystemTable; + + Ring3Data->EntryPoint = (VOID *)Ring3EntryPoint; + Ring3Data->BootServices = &mBootServices; + Ring3Data->RuntimeServices = &mRuntimeServices; + + gBS = &mBootServices; + gRT = &mRuntimeServices; + + CoreInitializePool (); + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf index ca5e9a0f5b..c4ba281f51 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf @@ -1,66 +1,66 @@ -## @file -# -# Ring3 driver for SysCalls. -# -# Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -# SPDX-License-Identifier: BSD-3-Clause -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = DxeRing3 - FILE_GUID = 88EA50C2-0DEA-4F13-B691-B506554E632B - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = Ring3Initialization - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 -# - -[Sources] - Ring3.h - DxeRing3.c - Ring3UefiBootServices.c - Ring3UefiRuntimeServices.c - Ring3Protocols.c - -[Sources.IA32] - IA32/SysCall.nasm - -[Sources.X64] - X64/SysCall.nasm - -[Sources.ARM] - ARM/SysCall.S - -[Sources.AARCH64] - AARCH64/SysCall.S - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - ArmPkg/ArmPkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - MemoryPoolLib - UefiBootServicesTableLib - UefiDriverEntryPoint - UefiRuntimeServicesTableLib - -[Protocols] - gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES - gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES - gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES - gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES - gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMES - gEfiUnicodeCollationProtocolGuid ## SOMETIMES_CONSUMES - -[Depex] - TRUE +## @file +# +# Ring3 driver for SysCalls. +# +# Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeRing3 + FILE_GUID = 88EA50C2-0DEA-4F13-B691-B506554E632B + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = Ring3Initialization + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 +# + +[Sources] + Ring3.h + DxeRing3.c + Ring3UefiBootServices.c + Ring3UefiRuntimeServices.c + Ring3Protocols.c + +[Sources.IA32] + IA32/SysCall.nasm + +[Sources.X64] + X64/SysCall.nasm + +[Sources.ARM] + ARM/SysCall.S + +[Sources.AARCH64] + AARCH64/SysCall.S + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ArmPkg/ArmPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryPoolLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiRuntimeServicesTableLib + +[Protocols] + gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES + gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES + gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMES + gEfiUnicodeCollationProtocolGuid ## SOMETIMES_CONSUMES + +[Depex] + TRUE diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm index 25817aded8..40e22ef83e 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm +++ b/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm @@ -1,42 +1,42 @@ -;------------------------------------------------------------------------------ -; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -; SPDX-License-Identifier: BSD-3-Clause -;------------------------------------------------------------------------------ - -extern ASM_PFX(Ring3Call) - -DEFAULT REL -SECTION .text - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; SysCall ( -; IN UINT8 Type, -; ... -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(SysCall) -ASM_PFX(SysCall): - mov edx, esp - mov ecx, [esp + 4] ; Type - lea eax, [userReturnAddress] - - sysenter -userReturnAddress: - ret - -;------------------------------------------------------------------------------ -; VOID -; EFIAPI -; Ring3EntryPoint ( -; IN RING3_CALL_DATA *Data -; ); -; -; (eax) Data -;------------------------------------------------------------------------------ -global ASM_PFX(Ring3EntryPoint) -ASM_PFX(Ring3EntryPoint): - push eax - - call ASM_PFX(Ring3Call) +;------------------------------------------------------------------------------ +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause +;------------------------------------------------------------------------------ + +extern ASM_PFX(Ring3Call) + +DEFAULT REL +SECTION .text + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; SysCall ( +; IN UINT8 Type, +; ... +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(SysCall) +ASM_PFX(SysCall): + mov edx, esp + mov ecx, [esp + 4] ; Type + lea eax, [userReturnAddress] + + sysenter +userReturnAddress: + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; Ring3EntryPoint ( +; IN RING3_CALL_DATA *Data +; ); +; +; (eax) Data +;------------------------------------------------------------------------------ +global ASM_PFX(Ring3EntryPoint) +ASM_PFX(Ring3EntryPoint): + push eax + + call ASM_PFX(Ring3Call) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h index 235af1eddb..a2d5e6416d 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h @@ -1,1628 +1,1628 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include -#include -#include -#include -#include - -EFI_STATUS -EFIAPI -SysCall ( - IN UINT8 Type, - ... - ); - -/** - Raise the task priority level to the new level. - High level is implemented by disabling processor interrupts. - - @param NewTpl New task priority level - - @return The previous task priority level - -**/ -EFI_TPL -EFIAPI -Ring3RaiseTpl ( - IN EFI_TPL NewTpl - ); - -/** - Lowers the task priority to the previous value. If the new - priority unmasks events at a higher priority, they are dispatched. - - @param NewTpl New, lower, task priority - -**/ -VOID -EFIAPI -Ring3RestoreTpl ( - IN EFI_TPL NewTpl - ); - -/** - Allocates pages from the memory map. - - @param Type The type of allocation to perform - @param MemoryType The type of memory to turn the allocated pages - into - @param NumberOfPages The number of pages to allocate - @param Memory A pointer to receive the base allocated memory - address - - @return Status. On success, Memory is filled in with the base address allocated - @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in - spec. - @retval EFI_NOT_FOUND Could not allocate pages match the requirement. - @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. - @retval EFI_SUCCESS Pages successfully allocated. - -**/ -EFI_STATUS -EFIAPI -Ring3AllocatePages ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, - IN OUT EFI_PHYSICAL_ADDRESS *Memory - ); - -/** - Frees previous allocated pages. - - @param Memory Base address of memory being freed - @param NumberOfPages The number of pages to free - - @retval EFI_NOT_FOUND Could not find the entry that covers the range - @retval EFI_INVALID_PARAMETER Address not aligned - @return EFI_SUCCESS -Pages successfully freed. - -**/ -EFI_STATUS -EFIAPI -Ring3FreePages ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages - ); - -/** - This function returns a copy of the current memory map. The map is an array of - memory descriptors, each of which describes a contiguous block of memory. - - @param MemoryMapSize A pointer to the size, in bytes, of the - MemoryMap buffer. On input, this is the size of - the buffer allocated by the caller. On output, - it is the size of the buffer returned by the - firmware if the buffer was large enough, or the - size of the buffer needed to contain the map if - the buffer was too small. - @param MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param MapKey A pointer to the location in which firmware - returns the key for the current memory map. - @param DescriptorSize A pointer to the location in which firmware - returns the size, in bytes, of an individual - EFI_MEMORY_DESCRIPTOR. - @param DescriptorVersion A pointer to the location in which firmware - returns the version number associated with the - EFI_MEMORY_DESCRIPTOR. - - @retval EFI_SUCCESS The memory map was returned in the MemoryMap - buffer. - @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current - buffer size needed to hold the memory map is - returned in MemoryMapSize. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - -**/ -EFI_STATUS -EFIAPI -Ring3GetMemoryMap ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion - ); - -/** - Creates an event. - - @param Type The type of event to create and its mode and - attributes - @param NotifyTpl The task priority level of event notifications - @param NotifyFunction Pointer to the events notification function - @param NotifyContext Pointer to the notification functions context; - corresponds to parameter "Context" in the - notification function - @param Event Pointer to the newly created event if the call - succeeds; undefined otherwise - - @retval EFI_SUCCESS The event structure was created - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value - @retval EFI_OUT_OF_RESOURCES The event could not be allocated - -**/ -EFI_STATUS -EFIAPI -Ring3CreateEvent ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, - IN VOID *NotifyContext OPTIONAL, - OUT EFI_EVENT *Event - ); - -/** - Sets the type of timer and the trigger time for a timer event. - - @param UserEvent The timer event that is to be signaled at the - specified time - @param Type The type of time that is specified in - TriggerTime - @param TriggerTime The number of 100ns units until the timer - expires - - @retval EFI_SUCCESS The event has been set to be signaled at the - requested time - @retval EFI_INVALID_PARAMETER Event or Type is not valid - -**/ -EFI_STATUS -EFIAPI -Ring3SetTimer ( - IN EFI_EVENT UserEvent, - IN EFI_TIMER_DELAY Type, - IN UINT64 TriggerTime - ); - -/** - Stops execution until an event is signaled. - - @param NumberOfEvents The number of events in the UserEvents array - @param UserEvents An array of EFI_EVENT - @param UserIndex Pointer to the index of the event which - satisfied the wait condition - - @retval EFI_SUCCESS The event indicated by Index was signaled. - @retval EFI_INVALID_PARAMETER The event indicated by Index has a notification - function or Event was not a valid type - @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION - -**/ -EFI_STATUS -EFIAPI -Ring3WaitForEvent ( - IN UINTN NumberOfEvents, - IN EFI_EVENT *UserEvents, - OUT UINTN *UserIndex - ); - -/** - Signals the event. Queues the event to be notified if needed. - - @param UserEvent The event to signal . - - @retval EFI_INVALID_PARAMETER Parameters are not valid. - @retval EFI_SUCCESS The event was signaled. - -**/ -EFI_STATUS -EFIAPI -Ring3SignalEvent ( - IN EFI_EVENT UserEvent - ); - -/** - Closes an event and frees the event structure. - - @param UserEvent Event to close - - @retval EFI_INVALID_PARAMETER Parameters are not valid. - @retval EFI_SUCCESS The event has been closed - -**/ -EFI_STATUS -EFIAPI -Ring3CloseEvent ( - IN EFI_EVENT UserEvent - ); - -/** - Check the status of an event. - - @param UserEvent The event to check - - @retval EFI_SUCCESS The event is in the signaled state - @retval EFI_NOT_READY The event is not in the signaled state - @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL - -**/ -EFI_STATUS -EFIAPI -Ring3CheckEvent ( - IN EFI_EVENT UserEvent - ); - -/** - Wrapper function to CoreInstallProtocolInterfaceNotify. This is the public API which - Calls the private one which contains a BOOLEAN parameter for notifications - - @param UserHandle The handle to install the protocol handler on, - or NULL if a new handle is to be allocated - @param Protocol The protocol to add to the handle - @param InterfaceType Indicates whether Interface is supplied in - native form. - @param Interface The interface for the protocol being added - - @return Status code - -**/ -EFI_STATUS -EFIAPI -Ring3InstallProtocolInterface ( - IN OUT EFI_HANDLE *UserHandle, - IN EFI_GUID *Protocol, - IN EFI_INTERFACE_TYPE InterfaceType, - IN VOID *Interface - ); - -/** - Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface. - - @param UserHandle Handle on which the interface is to be - reinstalled - @param Protocol The numeric ID of the interface - @param OldInterface A pointer to the old interface - @param NewInterface A pointer to the new interface - - @retval EFI_SUCCESS The protocol interface was installed - @retval EFI_NOT_FOUND The OldInterface on the handle was not found - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value - -**/ -EFI_STATUS -EFIAPI -Ring3ReinstallProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN VOID *OldInterface, - IN VOID *NewInterface - ); - -/** - Uninstalls all instances of a protocol:interfacer from a handle. - If the last protocol interface is remove from the handle, the - handle is freed. - - @param UserHandle The handle to remove the protocol handler from - @param Protocol The protocol, of protocol:interface, to remove - @param Interface The interface, of protocol:interface, to remove - - @retval EFI_INVALID_PARAMETER Protocol is NULL. - @retval EFI_SUCCESS Protocol interface successfully uninstalled. - -**/ -EFI_STATUS -EFIAPI -Ring3UninstallProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN VOID *Interface - ); - -/** - Queries a handle to determine if it supports a specified protocol. - - @param UserHandle The handle being queried. - @param Protocol The published unique identifier of the protocol. - @param Interface Supplies the address where a pointer to the - corresponding Protocol Interface is returned. - - @return The requested protocol interface for the handle - -**/ -EFI_STATUS -EFIAPI -Ring3HandleProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT VOID **Interface - ); - -/** - Add a new protocol notification record for the request protocol. - - @param Protocol The requested protocol to add the notify - registration - @param Event The event to signal - @param Registration Returns the registration record - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_SUCCESS Successfully returned the registration record - that has been added - -**/ -EFI_STATUS -EFIAPI -Ring3RegisterProtocolNotify ( - IN EFI_GUID *Protocol, - IN EFI_EVENT Event, - OUT VOID **Registration - ); - -/** - Locates the requested handle(s) and returns them in Buffer. - - @param SearchType The type of search to perform to locate the - handles - @param Protocol The protocol to search for - @param SearchKey Dependant on SearchType - @param BufferSize On input the size of Buffer. On output the - size of data returned. - @param Buffer The buffer to return the results in - - @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is - returned in BufferSize. - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_SUCCESS Successfully found the requested handle(s) and - returns them in Buffer. - -**/ -EFI_STATUS -EFIAPI -Ring3LocateHandle ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *BufferSize, - OUT EFI_HANDLE *Buffer - ); - -/** - Locates the handle to a device on the device path that best matches the specified protocol. - - @param Protocol The protocol to search for. - @param DevicePath On input, a pointer to a pointer to the device - path. On output, the device path pointer is - modified to point to the remaining part of the - devicepath. - @param Device A pointer to the returned device handle. - - @retval EFI_SUCCESS The resulting handle was returned. - @retval EFI_NOT_FOUND No handles matched the search. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - -**/ -EFI_STATUS -EFIAPI -Ring3LocateDevicePath ( - IN EFI_GUID *Protocol, - IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, - OUT EFI_HANDLE *Device - ); - -/** - Boot Service called to add, modify, or remove a system configuration table from - the EFI System Table. - - @param Guid Pointer to the GUID for the entry to add, update, or - remove - @param Table Pointer to the configuration table for the entry to add, - update, or remove, may be NULL. - - @return EFI_SUCCESS Guid, Table pair added, updated, or removed. - @return EFI_INVALID_PARAMETER Input GUID not valid. - @return EFI_NOT_FOUND Attempted to delete non-existant entry - @return EFI_OUT_OF_RESOURCES Not enough memory available - -**/ -EFI_STATUS -EFIAPI -Ring3InstallConfigurationTable ( - IN EFI_GUID *Guid, - IN VOID *Table - ); - -/** - Loads an EFI image into memory and returns a handle to the image. - - @param BootPolicy If TRUE, indicates that the request originates - from the boot manager, and that the boot - manager is attempting to load FilePath as a - boot selection. - @param ParentImageHandle The caller's image handle. - @param FilePath The specific file path from which the image is - loaded. - @param SourceBuffer If not NULL, a pointer to the memory location - containing a copy of the image to be loaded. - @param SourceSize The size in bytes of SourceBuffer. - @param ImageHandle Pointer to the returned image handle that is - created when the image is successfully loaded. - - @retval EFI_SUCCESS The image was loaded into memory. - @retval EFI_NOT_FOUND The FilePath was not found. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - @retval EFI_UNSUPPORTED The image type is not supported, or the device - path cannot be parsed to locate the proper - protocol for loading the file. - @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient - resources. - @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not - understood. - @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error. - @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the - image from being loaded. NULL is returned in *ImageHandle. - @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a - valid EFI_LOADED_IMAGE_PROTOCOL. However, the current - platform policy specifies that the image should not be started. - -**/ -EFI_STATUS -EFIAPI -Ring3LoadImage ( - IN BOOLEAN BootPolicy, - IN EFI_HANDLE ParentImageHandle, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN VOID *SourceBuffer OPTIONAL, - IN UINTN SourceSize, - OUT EFI_HANDLE *ImageHandle - ); - -/** - Transfer control to a loaded image's entry point. - - @param ImageHandle Handle of image to be started. - @param ExitDataSize Pointer of the size to ExitData - @param ExitData Pointer to a pointer to a data buffer that - includes a Null-terminated string, - optionally followed by additional binary data. - The string is a description that the caller may - use to further indicate the reason for the - image's exit. - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate - @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started. - @retval EFI_SUCCESS Successfully transfer control to the image's - entry point. - -**/ -EFI_STATUS -EFIAPI -Ring3StartImage ( - IN EFI_HANDLE ImageHandle, - OUT UINTN *ExitDataSize, - OUT CHAR16 **ExitData OPTIONAL - ); - -/** - Terminates the currently loaded EFI image and returns control to boot services. - - @param ImageHandle Handle that identifies the image. This - parameter is passed to the image on entry. - @param Status The image's exit code. - @param ExitDataSize The size, in bytes, of ExitData. Ignored if - ExitStatus is EFI_SUCCESS. - @param ExitData Pointer to a data buffer that includes a - Null-terminated Unicode string, optionally - followed by additional binary data. The string - is a description that the caller may use to - further indicate the reason for the image's - exit. - - @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current - image. - @retval EFI_SUCCESS Successfully terminates the currently loaded - EFI image. - @retval EFI_ACCESS_DENIED Should never reach there. - @retval EFI_OUT_OF_RESOURCES Could not allocate pool - -**/ -EFI_STATUS -EFIAPI -Ring3Exit ( - IN EFI_HANDLE ImageHandle, - IN EFI_STATUS Status, - IN UINTN ExitDataSize, - IN CHAR16 *ExitData OPTIONAL - ); - -/** - Unloads an image. - - @param ImageHandle Handle that identifies the image to be - unloaded. - - @retval EFI_SUCCESS The image has been unloaded. - @retval EFI_UNSUPPORTED The image has been started, and does not support - unload. - @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle. - -**/ -EFI_STATUS -EFIAPI -Ring3UnloadImage ( - IN EFI_HANDLE ImageHandle - ); - -/** - Terminates all boot services. - - @param ImageHandle Handle that identifies the exiting image. - @param MapKey Key to the latest memory map. - - @retval EFI_SUCCESS Boot Services terminated - @retval EFI_INVALID_PARAMETER MapKey is incorrect. - -**/ -EFI_STATUS -EFIAPI -Ring3ExitBootServices ( - IN EFI_HANDLE ImageHandle, - IN UINTN MapKey - ); - -/** - Returns a monotonically increasing count for the platform. - - @param[out] Count The pointer to returned value. - - @retval EFI_SUCCESS The next monotonic count was returned. - @retval EFI_INVALID_PARAMETER Count is NULL. - @retval EFI_DEVICE_ERROR The device is not functioning properly. - -**/ -EFI_STATUS -EFIAPI -Ring3GetNextMonotonicCount ( - OUT UINT64 *Count - ); - -/** - Introduces a fine-grained stall. - - @param Microseconds The number of microseconds to stall execution. - - @retval EFI_SUCCESS Execution was stalled for at least the requested - amount of microseconds. - @retval EFI_NOT_AVAILABLE_YET gMetronome is not available yet - -**/ -EFI_STATUS -EFIAPI -Ring3Stall ( - IN UINTN Microseconds - ); - -/** - Sets the system's watchdog timer. - - @param Timeout The number of seconds to set the watchdog timer to. - A value of zero disables the timer. - @param WatchdogCode The numeric code to log on a watchdog timer timeout - event. The firmware reserves codes 0x0000 to 0xFFFF. - Loaders and operating systems may use other timeout - codes. - @param DataSize The size, in bytes, of WatchdogData. - @param WatchdogData A data buffer that includes a Null-terminated Unicode - string, optionally followed by additional binary data. - The string is a description that the call may use to - further indicate the reason to be logged with a - watchdog event. - - @return EFI_SUCCESS Timeout has been set - @return EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet - @return EFI_UNSUPPORTED System does not have a timer (currently not used) - @return EFI_DEVICE_ERROR Could not complete due to hardware error - -**/ -EFI_STATUS -EFIAPI -Ring3SetWatchdogTimer ( - IN UINTN Timeout, - IN UINT64 WatchdogCode, - IN UINTN DataSize, - IN CHAR16 *WatchdogData OPTIONAL - ); - -/** - Connects one or more drivers to a controller. - - @param ControllerHandle The handle of the controller to which driver(s) are to be connected. - @param DriverImageHandle A pointer to an ordered list handles that support the - EFI_DRIVER_BINDING_PROTOCOL. - @param RemainingDevicePath A pointer to the device path that specifies a child of the - controller specified by ControllerHandle. - @param Recursive If TRUE, then ConnectController() is called recursively - until the entire tree of controllers below the controller specified - by ControllerHandle have been created. If FALSE, then - the tree of controllers is only expanded one level. - - @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle. - 2) No drivers were connected to ControllerHandle, but - RemainingDevicePath is not NULL, and it is an End Device - Path Node. - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances - present in the system. - 2) No drivers were connected to ControllerHandle. - @retval EFI_SECURITY_VIOLATION - The user has no permission to start UEFI device drivers on the device path - associated with the ControllerHandle or specified by the RemainingDevicePath. - -**/ -EFI_STATUS -EFIAPI -Ring3ConnectController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE *DriverImageHandle OPTIONAL, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, - IN BOOLEAN Recursive - ); - -/** - Disonnects a controller from a driver - - @param ControllerHandle ControllerHandle The handle of - the controller from which - driver(s) are to be - disconnected. - @param DriverImageHandle DriverImageHandle The driver to - disconnect from ControllerHandle. - @param ChildHandle ChildHandle The handle of the - child to destroy. - - @retval EFI_SUCCESS One or more drivers were - disconnected from the controller. - @retval EFI_SUCCESS On entry, no drivers are managing - ControllerHandle. - @retval EFI_SUCCESS DriverImageHandle is not NULL, - and on entry DriverImageHandle is - not managing ControllerHandle. - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL, - and it is not a valid EFI_HANDLE. - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it - is not a valid EFI_HANDLE. - @retval EFI_OUT_OF_RESOURCES There are not enough resources - available to disconnect any - drivers from ControllerHandle. - @retval EFI_DEVICE_ERROR The controller could not be - disconnected because of a device - error. - -**/ -EFI_STATUS -EFIAPI -Ring3DisconnectController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE DriverImageHandle OPTIONAL, - IN EFI_HANDLE ChildHandle OPTIONAL - ); - -/** - Locates the installed protocol handler for the handle, and - invokes it to obtain the protocol interface. Usage information - is registered in the protocol data base. - - @param UserHandle The handle to obtain the protocol interface on - @param Protocol The ID of the protocol - @param Interface The location to return the protocol interface - @param ImageHandle The handle of the Image that is opening the - protocol interface specified by Protocol and - Interface. - @param ControllerHandle The controller handle that is requiring this - interface. - @param Attributes The open mode of the protocol interface - specified by Handle and Protocol. - - @retval EFI_INVALID_PARAMETER Protocol is NULL. - @retval EFI_SUCCESS Get the protocol interface. - -**/ -EFI_STATUS -EFIAPI -Ring3OpenProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT VOID **Interface OPTIONAL, - IN EFI_HANDLE ImageHandle, - IN EFI_HANDLE ControllerHandle, - IN UINT32 Attributes - ); - -/** - Closes a protocol on a handle that was opened using OpenProtocol(). - - @param UserHandle The handle for the protocol interface that was - previously opened with OpenProtocol(), and is - now being closed. - @param Protocol The published unique identifier of the protocol. - It is the caller's responsibility to pass in a - valid GUID. - @param AgentHandle The handle of the agent that is closing the - protocol interface. - @param ControllerHandle If the agent that opened a protocol is a driver - that follows the EFI Driver Model, then this - parameter is the controller handle that required - the protocol interface. If the agent does not - follow the EFI Driver Model, then this parameter - is optional and may be NULL. - - @retval EFI_SUCCESS The protocol instance was closed. - @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a - valid EFI_HANDLE. - @retval EFI_NOT_FOUND Can not find the specified protocol or - AgentHandle. - -**/ -EFI_STATUS -EFIAPI -Ring3CloseProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN EFI_HANDLE AgentHandle, - IN EFI_HANDLE ControllerHandle - ); - -/** - Return information about Opened protocols in the system - - @param UserHandle The handle to close the protocol interface on - @param Protocol The ID of the protocol - @param EntryBuffer A pointer to a buffer of open protocol - information in the form of - EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures. - @param EntryCount Number of EntryBuffer entries - -**/ -EFI_STATUS -EFIAPI -Ring3OpenProtocolInformation ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, - OUT UINTN *EntryCount - ); - -/** - Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated - from pool. - - @param UserHandle The handle from which to retrieve the list of - protocol interface GUIDs. - @param ProtocolBuffer A pointer to the list of protocol interface GUID - pointers that are installed on Handle. - @param ProtocolBufferCount A pointer to the number of GUID pointers present - in ProtocolBuffer. - - @retval EFI_SUCCESS The list of protocol interface GUIDs installed - on Handle was returned in ProtocolBuffer. The - number of protocol interface GUIDs was returned - in ProtocolBufferCount. - @retval EFI_INVALID_PARAMETER Handle is NULL. - @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE. - @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL. - @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL. - @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the - results. - -**/ -EFI_STATUS -EFIAPI -Ring3ProtocolsPerHandle ( - IN EFI_HANDLE UserHandle, - OUT EFI_GUID ***ProtocolBuffer, - OUT UINTN *ProtocolBufferCount - ); - -/** - Function returns an array of handles that support the requested protocol - in a buffer allocated from pool. This is a version of Ring3LocateHandle() - that allocates a buffer for the caller. - - @param SearchType Specifies which handle(s) are to be returned. - @param Protocol Provides the protocol to search by. This - parameter is only valid for SearchType - ByProtocol. - @param SearchKey Supplies the search key depending on the - SearchType. - @param NumberHandles The number of handles returned in Buffer. - @param Buffer A pointer to the buffer to return the requested - array of handles that support Protocol. - - @retval EFI_SUCCESS The result array of handles was returned. - @retval EFI_NOT_FOUND No handles match the search. - @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the - matching results. - @retval EFI_INVALID_PARAMETER One or more parameters are not valid. - -**/ -EFI_STATUS -EFIAPI -Ring3LocateHandleBuffer ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *NumberHandles, - OUT EFI_HANDLE **Buffer - ); - -/** - Return the first Protocol Interface that matches the Protocol GUID. If - Registration is passed in, return a Protocol Instance that was just add - to the system. If Registration is NULL return the first Protocol Interface - you find. - - @param Protocol The protocol to search for - @param Registration Optional Registration Key returned from - RegisterProtocolNotify() - @param Interface Return the Protocol interface (instance). - - @retval EFI_SUCCESS If a valid Interface is returned - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_NOT_FOUND Protocol interface not found - -**/ -EFI_STATUS -EFIAPI -Ring3LocateProtocol ( - IN EFI_GUID *Protocol, - IN VOID *Registration OPTIONAL, - OUT VOID **Interface - ); - -/** - Installs a list of protocol interface into the boot services environment. - This function calls InstallProtocolInterface() in a loop. If any error - occures all the protocols added by this function are removed. This is - basically a lib function to save space. - - @param Handle The handle to install the protocol handlers on, - or NULL if a new handle is to be allocated - @param ... EFI_GUID followed by protocol instance. A NULL - terminates the list. The pairs are the - arguments to InstallProtocolInterface(). All the - protocols are added to Handle. - - @retval EFI_SUCCESS All the protocol interface was installed. - @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols. - @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in - the handle database. - @retval EFI_INVALID_PARAMETER Handle is NULL. - @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle. - -**/ -EFI_STATUS -EFIAPI -Ring3InstallMultipleProtocolInterfaces ( - IN OUT EFI_HANDLE *Handle, - ... - ); - -/** - Uninstalls a list of protocol interface in the boot services environment. - This function calls UnisatllProtocolInterface() in a loop. This is - basically a lib function to save space. - - @param Handle The handle to uninstall the protocol - @param ... EFI_GUID followed by protocol instance. A NULL - terminates the list. The pairs are the - arguments to UninstallProtocolInterface(). All - the protocols are added to Handle. - - @return Status code - -**/ -EFI_STATUS -EFIAPI -Ring3UninstallMultipleProtocolInterfaces ( - IN EFI_HANDLE Handle, - ... - ); - -/** - Computes and returns a 32-bit CRC for a data buffer. - - @param[in] Data A pointer to the buffer on which the 32-bit CRC is to be computed. - @param[in] DataSize The number of bytes in the buffer Data. - @param[out] Crc32 The 32-bit CRC that was computed for the data buffer specified by Data - and DataSize. - - @retval EFI_SUCCESS The 32-bit CRC was computed for the data buffer and returned in - Crc32. - @retval EFI_INVALID_PARAMETER Data is NULL. - @retval EFI_INVALID_PARAMETER Crc32 is NULL. - @retval EFI_INVALID_PARAMETER DataSize is 0. - -**/ -EFI_STATUS -EFIAPI -Ring3CalculateCrc32 ( - IN VOID *Data, - IN UINTN DataSize, - OUT UINT32 *Crc32 - ); - -/** - Creates an event in a group. - - @param Type The type of event to create and its mode and - attributes - @param NotifyTpl The task priority level of event notifications - @param NotifyFunction Pointer to the events notification function - @param NotifyContext Pointer to the notification functions context; - corresponds to parameter "Context" in the - notification function - @param EventGroup GUID for EventGroup if NULL act the same as - gBS->CreateEvent(). - @param Event Pointer to the newly created event if the call - succeeds; undefined otherwise - - @retval EFI_SUCCESS The event structure was created - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value - @retval EFI_OUT_OF_RESOURCES The event could not be allocated - -**/ -EFI_STATUS -EFIAPI -Ring3CreateEventEx ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, - IN CONST VOID *NotifyContext OPTIONAL, - IN CONST EFI_GUID *EventGroup OPTIONAL, - OUT EFI_EVENT *Event - ); - -/** - Reset the Block Device. - - @param This Indicates a pointer to the calling context. - @param ExtendedVerification Driver may perform diagnostics on reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -Ring3BlockIoReset ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ); - -/** - Read BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId Id of the media, changes every time the media is replaced. - @param Lba The starting Logical Block Address to read from - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the destination buffer for the data. The caller is - responsible for either having implicit or explicit ownership of the buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while performing the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -Ring3BlockIoRead ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - Write BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId The media ID that the write request is for. - @param Lba The starting logical block address to be written. The caller is - responsible for writing to only legitimate locations. - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the source buffer for the data. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -Ring3BlockIoWrite ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer - ); - -/** - Flush the Block Device. - - @param This Indicates a pointer to the calling context. - - @retval EFI_SUCCESS All outstanding data was written to the device - @retval EFI_DEVICE_ERROR The device reported an error while writting back the data - @retval EFI_NO_MEDIA There is no media in the device. - -**/ -EFI_STATUS -EFIAPI -Ring3BlockIoFlush ( - IN EFI_BLOCK_IO_PROTOCOL *This - ); - -/** - Read BufferSize bytes from Offset into Buffer. - - @param This Protocol instance pointer. - @param MediaId Id of the media, changes every time the media is replaced. - @param Offset The starting byte offset to read from - @param BufferSize Size of Buffer - @param Buffer Buffer containing read data - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while performing the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_INVALID_PARAMETER The read request contains device addresses that are not - valid for the device. - -**/ -EFI_STATUS -EFIAPI -Ring3DiskIoRead ( - IN EFI_DISK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Offset, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - Writes a specified number of bytes to a device. - - @param This Indicates a pointer to the calling context. - @param MediaId ID of the medium to be written. - @param Offset The starting byte offset on the logical block I/O device to write. - @param BufferSize The size in bytes of Buffer. The number of bytes to write to the device. - @param Buffer A pointer to the buffer containing the data to be written. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_INVALID_PARAMETER The write request contains device addresses that are not - valid for the device. - -**/ -EFI_STATUS -EFIAPI -Ring3DiskIoWrite ( - IN EFI_DISK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Offset, - IN UINTN BufferSize, - IN VOID *Buffer - ); - -/** - Returns the current time and date information, and the time-keeping capabilities - of the hardware platform. - - @param[out] Time A pointer to storage to receive a snapshot of the current time. - @param[out] Capabilities An optional pointer to a buffer to receive the real time clock - device's capabilities. - - @retval EFI_SUCCESS The operation completed successfully. - @retval EFI_INVALID_PARAMETER Time is NULL. - @retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error. - -**/ -EFI_STATUS -EFIAPI -Ring3GetTime ( - OUT EFI_TIME *Time, - OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL - ); - -/** - Sets the current local time and date information. - - @param[in] Time A pointer to the current time. - - @retval EFI_SUCCESS The operation completed successfully. - @retval EFI_INVALID_PARAMETER A time field is out of range. - @retval EFI_DEVICE_ERROR The time could not be set due due to hardware error. - -**/ -EFI_STATUS -EFIAPI -Ring3SetTime ( - IN EFI_TIME *Time - ); - -/** - Returns the current wakeup alarm clock setting. - - @param[out] Enabled Indicates if the alarm is currently enabled or disabled. - @param[out] Pending Indicates if the alarm signal is pending and requires acknowledgement. - @param[out] Time The current alarm setting. - - @retval EFI_SUCCESS The alarm settings were returned. - @retval EFI_INVALID_PARAMETER Enabled is NULL. - @retval EFI_INVALID_PARAMETER Pending is NULL. - @retval EFI_INVALID_PARAMETER Time is NULL. - @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error. - @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. - -**/ -EFI_STATUS -EFIAPI -Ring3GetWakeupTime ( - OUT BOOLEAN *Enabled, - OUT BOOLEAN *Pending, - OUT EFI_TIME *Time - ); - -/** - Sets the system wakeup alarm clock time. - - @param[in] Enable Enable or disable the wakeup alarm. - @param[in] Time If Enable is TRUE, the time to set the wakeup alarm for. - If Enable is FALSE, then this parameter is optional, and may be NULL. - - @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If - Enable is FALSE, then the wakeup alarm was disabled. - @retval EFI_INVALID_PARAMETER A time field is out of range. - @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error. - @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. - -**/ -EFI_STATUS -EFIAPI -Ring3SetWakeupTime ( - IN BOOLEAN Enable, - IN EFI_TIME *Time OPTIONAL - ); - -/** - Changes the runtime addressing mode of EFI firmware from physical to virtual. - - @param[in] MemoryMapSize The size in bytes of VirtualMap. - @param[in] DescriptorSize The size in bytes of an entry in the VirtualMap. - @param[in] DescriptorVersion The version of the structure entries in VirtualMap. - @param[in] VirtualMap An array of memory descriptors which contain new virtual - address mapping information for all runtime ranges. - - @retval EFI_SUCCESS The virtual address map has been applied. - @retval EFI_UNSUPPORTED EFI firmware is not at runtime, or the EFI firmware is already in - virtual address mapped mode. - @retval EFI_INVALID_PARAMETER DescriptorSize or DescriptorVersion is invalid. - @retval EFI_NO_MAPPING A virtual address was not supplied for a range in the memory - map that requires a mapping. - @retval EFI_NOT_FOUND A virtual address was supplied for an address that is not found - in the memory map. - -**/ -EFI_STATUS -EFIAPI -Ring3SetVirtualAddressMap ( - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize, - IN UINT32 DescriptorVersion, - IN EFI_MEMORY_DESCRIPTOR *VirtualMap - ); - -/** - Determines the new virtual address that is to be used on subsequent memory accesses. - - @param[in] DebugDisposition Supplies type information for the pointer being converted. - @param[in, out] Address A pointer to a pointer that is to be fixed to be the value needed - for the new virtual address mappings being applied. - - @retval EFI_SUCCESS The pointer pointed to by Address was modified. - @retval EFI_INVALID_PARAMETER 1) Address is NULL. - 2) *Address is NULL and DebugDisposition does - not have the EFI_OPTIONAL_PTR bit set. - @retval EFI_NOT_FOUND The pointer pointed to by Address was not found to be part - of the current memory map. This is normally fatal. - -**/ -EFI_STATUS -EFIAPI -Ring3ConvertPointer ( - IN UINTN DebugDisposition, - IN OUT VOID **Address - ); - -/** - Returns the value of a variable. - - @param[in] VariableName A Null-terminated string that is the name of the vendor's - variable. - @param[in] VendorGuid A unique identifier for the vendor. - @param[out] Attributes If not NULL, a pointer to the memory location to return the - attributes bitmask for the variable. - @param[in, out] DataSize On input, the size in bytes of the return Data buffer. - On output the size of data returned in Data. - @param[out] Data The buffer to return the contents of the variable. May be NULL - with a zero DataSize in order to determine the size buffer needed. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_NOT_FOUND The variable was not found. - @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. - @retval EFI_INVALID_PARAMETER VariableName is NULL. - @retval EFI_INVALID_PARAMETER VendorGuid is NULL. - @retval EFI_INVALID_PARAMETER DataSize is NULL. - @retval EFI_INVALID_PARAMETER The DataSize is not too small and Data is NULL. - @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. - @retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure. - -**/ -EFI_STATUS -EFIAPI -Ring3GetVariable ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - OUT UINT32 *Attributes OPTIONAL, - IN OUT UINTN *DataSize, - OUT VOID *Data OPTIONAL - ); - -/** - Enumerates the current variable names. - - @param[in, out] VariableNameSize The size of the VariableName buffer. The size must be large - enough to fit input string supplied in VariableName buffer. - @param[in, out] VariableName On input, supplies the last VariableName that was returned - by GetNextVariableName(). On output, returns the Nullterminated - string of the current variable. - @param[in, out] VendorGuid On input, supplies the last VendorGuid that was returned by - GetNextVariableName(). On output, returns the - VendorGuid of the current variable. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_NOT_FOUND The next variable was not found. - @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result. - VariableNameSize has been updated with the size needed to complete the request. - @retval EFI_INVALID_PARAMETER VariableNameSize is NULL. - @retval EFI_INVALID_PARAMETER VariableName is NULL. - @retval EFI_INVALID_PARAMETER VendorGuid is NULL. - @retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and - GUID of an existing variable. - @retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of - the input VariableName buffer. - @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. - -**/ -EFI_STATUS -EFIAPI -Ring3GetNextVariableName ( - IN OUT UINTN *VariableNameSize, - IN OUT CHAR16 *VariableName, - IN OUT EFI_GUID *VendorGuid - ); - -/** - Sets the value of a variable. - - @param[in] VariableName A Null-terminated string that is the name of the vendor's variable. - Each VariableName is unique for each VendorGuid. VariableName must - contain 1 or more characters. If VariableName is an empty string, - then EFI_INVALID_PARAMETER is returned. - @param[in] VendorGuid A unique identifier for the vendor. - @param[in] Attributes Attributes bitmask to set for the variable. - @param[in] DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE or - EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero - causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is - set, then a SetVariable() call with a DataSize of zero will not cause any change to - the variable value (the timestamp associated with the variable may be updated however - even if no new data value is provided,see the description of the - EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not - be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated). - @param[in] Data The contents for the variable. - - @retval EFI_SUCCESS The firmware has successfully stored the variable and its data as - defined by the Attributes. - @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied, or the - DataSize exceeds the maximum allowed. - @retval EFI_INVALID_PARAMETER VariableName is an empty string. - @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. - @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. - @retval EFI_WRITE_PROTECTED The variable in question is read-only. - @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted. - @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, - but the AuthInfo does NOT pass the validation check carried out by the firmware. - - @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. - -**/ -EFI_STATUS -EFIAPI -Ring3SetVariable ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - IN UINT32 Attributes, - IN UINTN DataSize, - IN VOID *Data - ); - -/** - Returns the next high 32 bits of the platform's monotonic counter. - - @param[out] HighCount The pointer to returned value. - - @retval EFI_SUCCESS The next high monotonic count was returned. - @retval EFI_INVALID_PARAMETER HighCount is NULL. - @retval EFI_DEVICE_ERROR The device is not functioning properly. - -**/ -EFI_STATUS -EFIAPI -Ring3GetNextHighMonotonicCount ( - OUT UINT32 *HighCount - ); - -/** - Resets the entire platform. - - @param[in] ResetType The type of reset to perform. - @param[in] ResetStatus The status code for the reset. - @param[in] DataSize The size, in bytes, of ResetData. - @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or - EfiResetShutdown the data buffer starts with a Null-terminated - string, optionally followed by additional binary data. - The string is a description that the caller may use to further - indicate the reason for the system reset. - For a ResetType of EfiResetPlatformSpecific the data buffer - also starts with a Null-terminated string that is followed - by an EFI_GUID that describes the specific type of reset to perform. -**/ -VOID -EFIAPI -Ring3ResetSystem ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN VOID *ResetData OPTIONAL - ); - -/** - Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended - consumption, the firmware may process the capsule immediately. If the payload should persist - across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities must - be passed into ResetSystem() and will cause the capsule to be processed by the firmware as - part of the reset process. - - @param[in] CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules - being passed into update capsule. - @param[in] CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in - CaspuleHeaderArray. - @param[in] ScatterGatherList Physical pointer to a set of - EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the - location in physical memory of a set of capsules. - - @retval EFI_SUCCESS Valid capsule was passed. If - CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the - capsule has been successfully processed by the firmware. - @retval EFI_INVALID_PARAMETER CapsuleSize is NULL, or an incompatible set of flags were - set in the capsule header. - @retval EFI_INVALID_PARAMETER CapsuleCount is 0. - @retval EFI_DEVICE_ERROR The capsule update was started, but failed due to a device error. - @retval EFI_UNSUPPORTED The capsule type is not supported on this platform. - @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule - is compatible with this platform but is not capable of being submitted or processed - in runtime. The caller may resubmit the capsule prior to ExitBootServices(). - @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates - the capsule is compatible with this platform but there are insufficient resources to process. - -**/ -EFI_STATUS -EFIAPI -Ring3UpdateCapsule ( - IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, - IN UINTN CapsuleCount, - IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL - ); - -/** - Returns if the capsule can be supported via UpdateCapsule(). - - @param[in] CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules - being passed into update capsule. - @param[in] CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in - CaspuleHeaderArray. - @param[out] MaxiumCapsuleSize On output the maximum size that UpdateCapsule() can - support as an argument to UpdateCapsule() via - CapsuleHeaderArray and ScatterGatherList. - @param[out] ResetType Returns the type of reset required for the capsule update. - - @retval EFI_SUCCESS Valid answer returned. - @retval EFI_UNSUPPORTED The capsule type is not supported on this platform, and - MaximumCapsuleSize and ResetType are undefined. - @retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL. - @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule - is compatible with this platform but is not capable of being submitted or processed - in runtime. The caller may resubmit the capsule prior to ExitBootServices(). - @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates - the capsule is compatible with this platform but there are insufficient resources to process. - -**/ -EFI_STATUS -EFIAPI -Ring3QueryCapsuleCapabilities ( - IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, - IN UINTN CapsuleCount, - OUT UINT64 *MaximumCapsuleSize, - OUT EFI_RESET_TYPE *ResetType - ); - -/** - Returns information about the EFI variables. - - @param[in] Attributes Attributes bitmask to specify the type of variables on - which to return information. - @param[out] MaximumVariableStorageSize On output the maximum size of the storage space - available for the EFI variables associated with the - attributes specified. - @param[out] RemainingVariableStorageSize Returns the remaining size of the storage space - available for the EFI variables associated with the - attributes specified. - @param[out] MaximumVariableSize Returns the maximum size of the individual EFI - variables associated with the attributes specified. - - @retval EFI_SUCCESS Valid answer returned. - @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied - @retval EFI_UNSUPPORTED The attribute is not supported on this platform, and the - MaximumVariableStorageSize, - RemainingVariableStorageSize, MaximumVariableSize - are undefined. - -**/ -EFI_STATUS -EFIAPI -Ring3QueryVariableInfo ( - IN UINT32 Attributes, - OUT UINT64 *MaximumVariableStorageSize, - OUT UINT64 *RemainingVariableStorageSize, - OUT UINT64 *MaximumVariableSize - ); - -/** - Performs a case-insensitive comparison of two Null-terminated strings. - - @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. - @param Str1 A pointer to a Null-terminated string. - @param Str2 A pointer to a Null-terminated string. - - @retval 0 Str1 is equivalent to Str2. - @retval >0 Str1 is lexically greater than Str2. - @retval <0 Str1 is lexically less than Str2. - -**/ -INTN -EFIAPI -Ring3UnicodeStriColl ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *Str1, - IN CHAR16 *Str2 - ); - -/** - Performs a case-insensitive comparison of a Null-terminated - pattern string and a Null-terminated string. - - @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. - @param String A pointer to a Null-terminated string. - @param Pattern A pointer to a Null-terminated pattern string. - - @retval TRUE Pattern was found in String. - @retval FALSE Pattern was not found in String. - -**/ -BOOLEAN -EFIAPI -Ring3UnicodeMetaiMatch ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *String, - IN CHAR16 *Pattern - ); - -/** - Converts all the characters in a Null-terminated string to - lower case characters. - - @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. - @param String A pointer to a Null-terminated string. - -**/ -VOID -EFIAPI -Ring3UnicodeStrLwr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str - ); - -/** - Converts all the characters in a Null-terminated string to upper - case characters. - - @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. - @param String A pointer to a Null-terminated string. - -**/ -VOID -EFIAPI -Ring3UnicodeStrUpr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str - ); - -/** - Converts an 8.3 FAT file name in an OEM character set to a Null-terminated - string. - - @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. - @param FatSize The size of the string Fat in bytes. - @param Fat A pointer to a Null-terminated string that contains an 8.3 file - name using an 8-bit OEM character set. - @param String A pointer to a Null-terminated string. The string must - be allocated in advance to hold FatSize characters. - -**/ -VOID -EFIAPI -Ring3UnicodeFatToStr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN UINTN FatSize, - IN CHAR8 *Fat, - OUT CHAR16 *String - ); - -/** - Converts a Null-terminated string to legal characters in a FAT - filename using an OEM character set. - - @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. - @param String A pointer to a Null-terminated string. - @param FatSize The size of the string Fat in bytes. - @param Fat A pointer to a string that contains the converted version of - String using legal FAT characters from an OEM character set. - - @retval TRUE One or more conversions failed and were substituted with '_' - @retval FALSE None of the conversions failed. - -**/ -BOOLEAN -EFIAPI -Ring3UnicodeStrToFat ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *String, - IN UINTN FatSize, - OUT CHAR8 *Fat - ); +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include +#include +#include +#include +#include + +EFI_STATUS +EFIAPI +SysCall ( + IN UINT8 Type, + ... + ); + +/** + Raise the task priority level to the new level. + High level is implemented by disabling processor interrupts. + + @param NewTpl New task priority level + + @return The previous task priority level + +**/ +EFI_TPL +EFIAPI +Ring3RaiseTpl ( + IN EFI_TPL NewTpl + ); + +/** + Lowers the task priority to the previous value. If the new + priority unmasks events at a higher priority, they are dispatched. + + @param NewTpl New, lower, task priority + +**/ +VOID +EFIAPI +Ring3RestoreTpl ( + IN EFI_TPL NewTpl + ); + +/** + Allocates pages from the memory map. + + @param Type The type of allocation to perform + @param MemoryType The type of memory to turn the allocated pages + into + @param NumberOfPages The number of pages to allocate + @param Memory A pointer to receive the base allocated memory + address + + @return Status. On success, Memory is filled in with the base address allocated + @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in + spec. + @retval EFI_NOT_FOUND Could not allocate pages match the requirement. + @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. + @retval EFI_SUCCESS Pages successfully allocated. + +**/ +EFI_STATUS +EFIAPI +Ring3AllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NumberOfPages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ); + +/** + Frees previous allocated pages. + + @param Memory Base address of memory being freed + @param NumberOfPages The number of pages to free + + @retval EFI_NOT_FOUND Could not find the entry that covers the range + @retval EFI_INVALID_PARAMETER Address not aligned + @return EFI_SUCCESS -Pages successfully freed. + +**/ +EFI_STATUS +EFIAPI +Ring3FreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ); + +/** + This function returns a copy of the current memory map. The map is an array of + memory descriptors, each of which describes a contiguous block of memory. + + @param MemoryMapSize A pointer to the size, in bytes, of the + MemoryMap buffer. On input, this is the size of + the buffer allocated by the caller. On output, + it is the size of the buffer returned by the + firmware if the buffer was large enough, or the + size of the buffer needed to contain the map if + the buffer was too small. + @param MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param MapKey A pointer to the location in which firmware + returns the key for the current memory map. + @param DescriptorSize A pointer to the location in which firmware + returns the size, in bytes, of an individual + EFI_MEMORY_DESCRIPTOR. + @param DescriptorVersion A pointer to the location in which firmware + returns the version number associated with the + EFI_MEMORY_DESCRIPTOR. + + @retval EFI_SUCCESS The memory map was returned in the MemoryMap + buffer. + @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current + buffer size needed to hold the memory map is + returned in MemoryMapSize. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +EFI_STATUS +EFIAPI +Ring3GetMemoryMap ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ); + +/** + Creates an event. + + @param Type The type of event to create and its mode and + attributes + @param NotifyTpl The task priority level of event notifications + @param NotifyFunction Pointer to the events notification function + @param NotifyContext Pointer to the notification functions context; + corresponds to parameter "Context" in the + notification function + @param Event Pointer to the newly created event if the call + succeeds; undefined otherwise + + @retval EFI_SUCCESS The event structure was created + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value + @retval EFI_OUT_OF_RESOURCES The event could not be allocated + +**/ +EFI_STATUS +EFIAPI +Ring3CreateEvent ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN VOID *NotifyContext OPTIONAL, + OUT EFI_EVENT *Event + ); + +/** + Sets the type of timer and the trigger time for a timer event. + + @param UserEvent The timer event that is to be signaled at the + specified time + @param Type The type of time that is specified in + TriggerTime + @param TriggerTime The number of 100ns units until the timer + expires + + @retval EFI_SUCCESS The event has been set to be signaled at the + requested time + @retval EFI_INVALID_PARAMETER Event or Type is not valid + +**/ +EFI_STATUS +EFIAPI +Ring3SetTimer ( + IN EFI_EVENT UserEvent, + IN EFI_TIMER_DELAY Type, + IN UINT64 TriggerTime + ); + +/** + Stops execution until an event is signaled. + + @param NumberOfEvents The number of events in the UserEvents array + @param UserEvents An array of EFI_EVENT + @param UserIndex Pointer to the index of the event which + satisfied the wait condition + + @retval EFI_SUCCESS The event indicated by Index was signaled. + @retval EFI_INVALID_PARAMETER The event indicated by Index has a notification + function or Event was not a valid type + @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION + +**/ +EFI_STATUS +EFIAPI +Ring3WaitForEvent ( + IN UINTN NumberOfEvents, + IN EFI_EVENT *UserEvents, + OUT UINTN *UserIndex + ); + +/** + Signals the event. Queues the event to be notified if needed. + + @param UserEvent The event to signal . + + @retval EFI_INVALID_PARAMETER Parameters are not valid. + @retval EFI_SUCCESS The event was signaled. + +**/ +EFI_STATUS +EFIAPI +Ring3SignalEvent ( + IN EFI_EVENT UserEvent + ); + +/** + Closes an event and frees the event structure. + + @param UserEvent Event to close + + @retval EFI_INVALID_PARAMETER Parameters are not valid. + @retval EFI_SUCCESS The event has been closed + +**/ +EFI_STATUS +EFIAPI +Ring3CloseEvent ( + IN EFI_EVENT UserEvent + ); + +/** + Check the status of an event. + + @param UserEvent The event to check + + @retval EFI_SUCCESS The event is in the signaled state + @retval EFI_NOT_READY The event is not in the signaled state + @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL + +**/ +EFI_STATUS +EFIAPI +Ring3CheckEvent ( + IN EFI_EVENT UserEvent + ); + +/** + Wrapper function to CoreInstallProtocolInterfaceNotify. This is the public API which + Calls the private one which contains a BOOLEAN parameter for notifications + + @param UserHandle The handle to install the protocol handler on, + or NULL if a new handle is to be allocated + @param Protocol The protocol to add to the handle + @param InterfaceType Indicates whether Interface is supplied in + native form. + @param Interface The interface for the protocol being added + + @return Status code + +**/ +EFI_STATUS +EFIAPI +Ring3InstallProtocolInterface ( + IN OUT EFI_HANDLE *UserHandle, + IN EFI_GUID *Protocol, + IN EFI_INTERFACE_TYPE InterfaceType, + IN VOID *Interface + ); + +/** + Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface. + + @param UserHandle Handle on which the interface is to be + reinstalled + @param Protocol The numeric ID of the interface + @param OldInterface A pointer to the old interface + @param NewInterface A pointer to the new interface + + @retval EFI_SUCCESS The protocol interface was installed + @retval EFI_NOT_FOUND The OldInterface on the handle was not found + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value + +**/ +EFI_STATUS +EFIAPI +Ring3ReinstallProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN VOID *OldInterface, + IN VOID *NewInterface + ); + +/** + Uninstalls all instances of a protocol:interfacer from a handle. + If the last protocol interface is remove from the handle, the + handle is freed. + + @param UserHandle The handle to remove the protocol handler from + @param Protocol The protocol, of protocol:interface, to remove + @param Interface The interface, of protocol:interface, to remove + + @retval EFI_INVALID_PARAMETER Protocol is NULL. + @retval EFI_SUCCESS Protocol interface successfully uninstalled. + +**/ +EFI_STATUS +EFIAPI +Ring3UninstallProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN VOID *Interface + ); + +/** + Queries a handle to determine if it supports a specified protocol. + + @param UserHandle The handle being queried. + @param Protocol The published unique identifier of the protocol. + @param Interface Supplies the address where a pointer to the + corresponding Protocol Interface is returned. + + @return The requested protocol interface for the handle + +**/ +EFI_STATUS +EFIAPI +Ring3HandleProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface + ); + +/** + Add a new protocol notification record for the request protocol. + + @param Protocol The requested protocol to add the notify + registration + @param Event The event to signal + @param Registration Returns the registration record + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCCESS Successfully returned the registration record + that has been added + +**/ +EFI_STATUS +EFIAPI +Ring3RegisterProtocolNotify ( + IN EFI_GUID *Protocol, + IN EFI_EVENT Event, + OUT VOID **Registration + ); + +/** + Locates the requested handle(s) and returns them in Buffer. + + @param SearchType The type of search to perform to locate the + handles + @param Protocol The protocol to search for + @param SearchKey Dependant on SearchType + @param BufferSize On input the size of Buffer. On output the + size of data returned. + @param Buffer The buffer to return the results in + + @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is + returned in BufferSize. + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCCESS Successfully found the requested handle(s) and + returns them in Buffer. + +**/ +EFI_STATUS +EFIAPI +Ring3LocateHandle ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer + ); + +/** + Locates the handle to a device on the device path that best matches the specified protocol. + + @param Protocol The protocol to search for. + @param DevicePath On input, a pointer to a pointer to the device + path. On output, the device path pointer is + modified to point to the remaining part of the + devicepath. + @param Device A pointer to the returned device handle. + + @retval EFI_SUCCESS The resulting handle was returned. + @retval EFI_NOT_FOUND No handles matched the search. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +EFI_STATUS +EFIAPI +Ring3LocateDevicePath ( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, + OUT EFI_HANDLE *Device + ); + +/** + Boot Service called to add, modify, or remove a system configuration table from + the EFI System Table. + + @param Guid Pointer to the GUID for the entry to add, update, or + remove + @param Table Pointer to the configuration table for the entry to add, + update, or remove, may be NULL. + + @return EFI_SUCCESS Guid, Table pair added, updated, or removed. + @return EFI_INVALID_PARAMETER Input GUID not valid. + @return EFI_NOT_FOUND Attempted to delete non-existant entry + @return EFI_OUT_OF_RESOURCES Not enough memory available + +**/ +EFI_STATUS +EFIAPI +Ring3InstallConfigurationTable ( + IN EFI_GUID *Guid, + IN VOID *Table + ); + +/** + Loads an EFI image into memory and returns a handle to the image. + + @param BootPolicy If TRUE, indicates that the request originates + from the boot manager, and that the boot + manager is attempting to load FilePath as a + boot selection. + @param ParentImageHandle The caller's image handle. + @param FilePath The specific file path from which the image is + loaded. + @param SourceBuffer If not NULL, a pointer to the memory location + containing a copy of the image to be loaded. + @param SourceSize The size in bytes of SourceBuffer. + @param ImageHandle Pointer to the returned image handle that is + created when the image is successfully loaded. + + @retval EFI_SUCCESS The image was loaded into memory. + @retval EFI_NOT_FOUND The FilePath was not found. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_UNSUPPORTED The image type is not supported, or the device + path cannot be parsed to locate the proper + protocol for loading the file. + @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient + resources. + @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not + understood. + @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error. + @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the + image from being loaded. NULL is returned in *ImageHandle. + @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a + valid EFI_LOADED_IMAGE_PROTOCOL. However, the current + platform policy specifies that the image should not be started. + +**/ +EFI_STATUS +EFIAPI +Ring3LoadImage ( + IN BOOLEAN BootPolicy, + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + OUT EFI_HANDLE *ImageHandle + ); + +/** + Transfer control to a loaded image's entry point. + + @param ImageHandle Handle of image to be started. + @param ExitDataSize Pointer of the size to ExitData + @param ExitData Pointer to a pointer to a data buffer that + includes a Null-terminated string, + optionally followed by additional binary data. + The string is a description that the caller may + use to further indicate the reason for the + image's exit. + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate + @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started. + @retval EFI_SUCCESS Successfully transfer control to the image's + entry point. + +**/ +EFI_STATUS +EFIAPI +Ring3StartImage ( + IN EFI_HANDLE ImageHandle, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL + ); + +/** + Terminates the currently loaded EFI image and returns control to boot services. + + @param ImageHandle Handle that identifies the image. This + parameter is passed to the image on entry. + @param Status The image's exit code. + @param ExitDataSize The size, in bytes, of ExitData. Ignored if + ExitStatus is EFI_SUCCESS. + @param ExitData Pointer to a data buffer that includes a + Null-terminated Unicode string, optionally + followed by additional binary data. The string + is a description that the caller may use to + further indicate the reason for the image's + exit. + + @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current + image. + @retval EFI_SUCCESS Successfully terminates the currently loaded + EFI image. + @retval EFI_ACCESS_DENIED Should never reach there. + @retval EFI_OUT_OF_RESOURCES Could not allocate pool + +**/ +EFI_STATUS +EFIAPI +Ring3Exit ( + IN EFI_HANDLE ImageHandle, + IN EFI_STATUS Status, + IN UINTN ExitDataSize, + IN CHAR16 *ExitData OPTIONAL + ); + +/** + Unloads an image. + + @param ImageHandle Handle that identifies the image to be + unloaded. + + @retval EFI_SUCCESS The image has been unloaded. + @retval EFI_UNSUPPORTED The image has been started, and does not support + unload. + @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle. + +**/ +EFI_STATUS +EFIAPI +Ring3UnloadImage ( + IN EFI_HANDLE ImageHandle + ); + +/** + Terminates all boot services. + + @param ImageHandle Handle that identifies the exiting image. + @param MapKey Key to the latest memory map. + + @retval EFI_SUCCESS Boot Services terminated + @retval EFI_INVALID_PARAMETER MapKey is incorrect. + +**/ +EFI_STATUS +EFIAPI +Ring3ExitBootServices ( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey + ); + +/** + Returns a monotonically increasing count for the platform. + + @param[out] Count The pointer to returned value. + + @retval EFI_SUCCESS The next monotonic count was returned. + @retval EFI_INVALID_PARAMETER Count is NULL. + @retval EFI_DEVICE_ERROR The device is not functioning properly. + +**/ +EFI_STATUS +EFIAPI +Ring3GetNextMonotonicCount ( + OUT UINT64 *Count + ); + +/** + Introduces a fine-grained stall. + + @param Microseconds The number of microseconds to stall execution. + + @retval EFI_SUCCESS Execution was stalled for at least the requested + amount of microseconds. + @retval EFI_NOT_AVAILABLE_YET gMetronome is not available yet + +**/ +EFI_STATUS +EFIAPI +Ring3Stall ( + IN UINTN Microseconds + ); + +/** + Sets the system's watchdog timer. + + @param Timeout The number of seconds to set the watchdog timer to. + A value of zero disables the timer. + @param WatchdogCode The numeric code to log on a watchdog timer timeout + event. The firmware reserves codes 0x0000 to 0xFFFF. + Loaders and operating systems may use other timeout + codes. + @param DataSize The size, in bytes, of WatchdogData. + @param WatchdogData A data buffer that includes a Null-terminated Unicode + string, optionally followed by additional binary data. + The string is a description that the call may use to + further indicate the reason to be logged with a + watchdog event. + + @return EFI_SUCCESS Timeout has been set + @return EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet + @return EFI_UNSUPPORTED System does not have a timer (currently not used) + @return EFI_DEVICE_ERROR Could not complete due to hardware error + +**/ +EFI_STATUS +EFIAPI +Ring3SetWatchdogTimer ( + IN UINTN Timeout, + IN UINT64 WatchdogCode, + IN UINTN DataSize, + IN CHAR16 *WatchdogData OPTIONAL + ); + +/** + Connects one or more drivers to a controller. + + @param ControllerHandle The handle of the controller to which driver(s) are to be connected. + @param DriverImageHandle A pointer to an ordered list handles that support the + EFI_DRIVER_BINDING_PROTOCOL. + @param RemainingDevicePath A pointer to the device path that specifies a child of the + controller specified by ControllerHandle. + @param Recursive If TRUE, then ConnectController() is called recursively + until the entire tree of controllers below the controller specified + by ControllerHandle have been created. If FALSE, then + the tree of controllers is only expanded one level. + + @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle. + 2) No drivers were connected to ControllerHandle, but + RemainingDevicePath is not NULL, and it is an End Device + Path Node. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances + present in the system. + 2) No drivers were connected to ControllerHandle. + @retval EFI_SECURITY_VIOLATION + The user has no permission to start UEFI device drivers on the device path + associated with the ControllerHandle or specified by the RemainingDevicePath. + +**/ +EFI_STATUS +EFIAPI +Ring3ConnectController ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE *DriverImageHandle OPTIONAL, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, + IN BOOLEAN Recursive + ); + +/** + Disonnects a controller from a driver + + @param ControllerHandle ControllerHandle The handle of + the controller from which + driver(s) are to be + disconnected. + @param DriverImageHandle DriverImageHandle The driver to + disconnect from ControllerHandle. + @param ChildHandle ChildHandle The handle of the + child to destroy. + + @retval EFI_SUCCESS One or more drivers were + disconnected from the controller. + @retval EFI_SUCCESS On entry, no drivers are managing + ControllerHandle. + @retval EFI_SUCCESS DriverImageHandle is not NULL, + and on entry DriverImageHandle is + not managing ControllerHandle. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL, + and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it + is not a valid EFI_HANDLE. + @retval EFI_OUT_OF_RESOURCES There are not enough resources + available to disconnect any + drivers from ControllerHandle. + @retval EFI_DEVICE_ERROR The controller could not be + disconnected because of a device + error. + +**/ +EFI_STATUS +EFIAPI +Ring3DisconnectController ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverImageHandle OPTIONAL, + IN EFI_HANDLE ChildHandle OPTIONAL + ); + +/** + Locates the installed protocol handler for the handle, and + invokes it to obtain the protocol interface. Usage information + is registered in the protocol data base. + + @param UserHandle The handle to obtain the protocol interface on + @param Protocol The ID of the protocol + @param Interface The location to return the protocol interface + @param ImageHandle The handle of the Image that is opening the + protocol interface specified by Protocol and + Interface. + @param ControllerHandle The controller handle that is requiring this + interface. + @param Attributes The open mode of the protocol interface + specified by Handle and Protocol. + + @retval EFI_INVALID_PARAMETER Protocol is NULL. + @retval EFI_SUCCESS Get the protocol interface. + +**/ +EFI_STATUS +EFIAPI +Ring3OpenProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface OPTIONAL, + IN EFI_HANDLE ImageHandle, + IN EFI_HANDLE ControllerHandle, + IN UINT32 Attributes + ); + +/** + Closes a protocol on a handle that was opened using OpenProtocol(). + + @param UserHandle The handle for the protocol interface that was + previously opened with OpenProtocol(), and is + now being closed. + @param Protocol The published unique identifier of the protocol. + It is the caller's responsibility to pass in a + valid GUID. + @param AgentHandle The handle of the agent that is closing the + protocol interface. + @param ControllerHandle If the agent that opened a protocol is a driver + that follows the EFI Driver Model, then this + parameter is the controller handle that required + the protocol interface. If the agent does not + follow the EFI Driver Model, then this parameter + is optional and may be NULL. + + @retval EFI_SUCCESS The protocol instance was closed. + @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a + valid EFI_HANDLE. + @retval EFI_NOT_FOUND Can not find the specified protocol or + AgentHandle. + +**/ +EFI_STATUS +EFIAPI +Ring3CloseProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN EFI_HANDLE AgentHandle, + IN EFI_HANDLE ControllerHandle + ); + +/** + Return information about Opened protocols in the system + + @param UserHandle The handle to close the protocol interface on + @param Protocol The ID of the protocol + @param EntryBuffer A pointer to a buffer of open protocol + information in the form of + EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures. + @param EntryCount Number of EntryBuffer entries + +**/ +EFI_STATUS +EFIAPI +Ring3OpenProtocolInformation ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, + OUT UINTN *EntryCount + ); + +/** + Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated + from pool. + + @param UserHandle The handle from which to retrieve the list of + protocol interface GUIDs. + @param ProtocolBuffer A pointer to the list of protocol interface GUID + pointers that are installed on Handle. + @param ProtocolBufferCount A pointer to the number of GUID pointers present + in ProtocolBuffer. + + @retval EFI_SUCCESS The list of protocol interface GUIDs installed + on Handle was returned in ProtocolBuffer. The + number of protocol interface GUIDs was returned + in ProtocolBufferCount. + @retval EFI_INVALID_PARAMETER Handle is NULL. + @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL. + @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL. + @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the + results. + +**/ +EFI_STATUS +EFIAPI +Ring3ProtocolsPerHandle ( + IN EFI_HANDLE UserHandle, + OUT EFI_GUID ***ProtocolBuffer, + OUT UINTN *ProtocolBufferCount + ); + +/** + Function returns an array of handles that support the requested protocol + in a buffer allocated from pool. This is a version of Ring3LocateHandle() + that allocates a buffer for the caller. + + @param SearchType Specifies which handle(s) are to be returned. + @param Protocol Provides the protocol to search by. This + parameter is only valid for SearchType + ByProtocol. + @param SearchKey Supplies the search key depending on the + SearchType. + @param NumberHandles The number of handles returned in Buffer. + @param Buffer A pointer to the buffer to return the requested + array of handles that support Protocol. + + @retval EFI_SUCCESS The result array of handles was returned. + @retval EFI_NOT_FOUND No handles match the search. + @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the + matching results. + @retval EFI_INVALID_PARAMETER One or more parameters are not valid. + +**/ +EFI_STATUS +EFIAPI +Ring3LocateHandleBuffer ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NumberHandles, + OUT EFI_HANDLE **Buffer + ); + +/** + Return the first Protocol Interface that matches the Protocol GUID. If + Registration is passed in, return a Protocol Instance that was just add + to the system. If Registration is NULL return the first Protocol Interface + you find. + + @param Protocol The protocol to search for + @param Registration Optional Registration Key returned from + RegisterProtocolNotify() + @param Interface Return the Protocol interface (instance). + + @retval EFI_SUCCESS If a valid Interface is returned + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_NOT_FOUND Protocol interface not found + +**/ +EFI_STATUS +EFIAPI +Ring3LocateProtocol ( + IN EFI_GUID *Protocol, + IN VOID *Registration OPTIONAL, + OUT VOID **Interface + ); + +/** + Installs a list of protocol interface into the boot services environment. + This function calls InstallProtocolInterface() in a loop. If any error + occures all the protocols added by this function are removed. This is + basically a lib function to save space. + + @param Handle The handle to install the protocol handlers on, + or NULL if a new handle is to be allocated + @param ... EFI_GUID followed by protocol instance. A NULL + terminates the list. The pairs are the + arguments to InstallProtocolInterface(). All the + protocols are added to Handle. + + @retval EFI_SUCCESS All the protocol interface was installed. + @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols. + @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in + the handle database. + @retval EFI_INVALID_PARAMETER Handle is NULL. + @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle. + +**/ +EFI_STATUS +EFIAPI +Ring3InstallMultipleProtocolInterfaces ( + IN OUT EFI_HANDLE *Handle, + ... + ); + +/** + Uninstalls a list of protocol interface in the boot services environment. + This function calls UnisatllProtocolInterface() in a loop. This is + basically a lib function to save space. + + @param Handle The handle to uninstall the protocol + @param ... EFI_GUID followed by protocol instance. A NULL + terminates the list. The pairs are the + arguments to UninstallProtocolInterface(). All + the protocols are added to Handle. + + @return Status code + +**/ +EFI_STATUS +EFIAPI +Ring3UninstallMultipleProtocolInterfaces ( + IN EFI_HANDLE Handle, + ... + ); + +/** + Computes and returns a 32-bit CRC for a data buffer. + + @param[in] Data A pointer to the buffer on which the 32-bit CRC is to be computed. + @param[in] DataSize The number of bytes in the buffer Data. + @param[out] Crc32 The 32-bit CRC that was computed for the data buffer specified by Data + and DataSize. + + @retval EFI_SUCCESS The 32-bit CRC was computed for the data buffer and returned in + Crc32. + @retval EFI_INVALID_PARAMETER Data is NULL. + @retval EFI_INVALID_PARAMETER Crc32 is NULL. + @retval EFI_INVALID_PARAMETER DataSize is 0. + +**/ +EFI_STATUS +EFIAPI +Ring3CalculateCrc32 ( + IN VOID *Data, + IN UINTN DataSize, + OUT UINT32 *Crc32 + ); + +/** + Creates an event in a group. + + @param Type The type of event to create and its mode and + attributes + @param NotifyTpl The task priority level of event notifications + @param NotifyFunction Pointer to the events notification function + @param NotifyContext Pointer to the notification functions context; + corresponds to parameter "Context" in the + notification function + @param EventGroup GUID for EventGroup if NULL act the same as + gBS->CreateEvent(). + @param Event Pointer to the newly created event if the call + succeeds; undefined otherwise + + @retval EFI_SUCCESS The event structure was created + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value + @retval EFI_OUT_OF_RESOURCES The event could not be allocated + +**/ +EFI_STATUS +EFIAPI +Ring3CreateEventEx ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN CONST VOID *NotifyContext OPTIONAL, + IN CONST EFI_GUID *EventGroup OPTIONAL, + OUT EFI_EVENT *Event + ); + +/** + Reset the Block Device. + + @param This Indicates a pointer to the calling context. + @param ExtendedVerification Driver may perform diagnostics on reset. + + @retval EFI_SUCCESS The device was reset. + @retval EFI_DEVICE_ERROR The device is not functioning properly and could + not be reset. + +**/ +EFI_STATUS +EFIAPI +Ring3BlockIoReset ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +/** + Read BufferSize bytes from Lba into Buffer. + + @param This Indicates a pointer to the calling context. + @param MediaId Id of the media, changes every time the media is replaced. + @param Lba The starting Logical Block Address to read from + @param BufferSize Size of Buffer, must be a multiple of device block size. + @param Buffer A pointer to the destination buffer for the data. The caller is + responsible for either having implicit or explicit ownership of the buffer. + + @retval EFI_SUCCESS The data was read correctly from the device. + @retval EFI_DEVICE_ERROR The device reported an error while performing the read. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device. + @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. + @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, + or the buffer is not on proper alignment. + +**/ +EFI_STATUS +EFIAPI +Ring3BlockIoRead ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + +/** + Write BufferSize bytes from Lba into Buffer. + + @param This Indicates a pointer to the calling context. + @param MediaId The media ID that the write request is for. + @param Lba The starting logical block address to be written. The caller is + responsible for writing to only legitimate locations. + @param BufferSize Size of Buffer, must be a multiple of device block size. + @param Buffer A pointer to the source buffer for the data. + + @retval EFI_SUCCESS The data was written correctly to the device. + @retval EFI_WRITE_PROTECTED The device can not be written to. + @retval EFI_DEVICE_ERROR The device reported an error while performing the write. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. + @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, + or the buffer is not on proper alignment. + +**/ +EFI_STATUS +EFIAPI +Ring3BlockIoWrite ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +/** + Flush the Block Device. + + @param This Indicates a pointer to the calling context. + + @retval EFI_SUCCESS All outstanding data was written to the device + @retval EFI_DEVICE_ERROR The device reported an error while writting back the data + @retval EFI_NO_MEDIA There is no media in the device. + +**/ +EFI_STATUS +EFIAPI +Ring3BlockIoFlush ( + IN EFI_BLOCK_IO_PROTOCOL *This + ); + +/** + Read BufferSize bytes from Offset into Buffer. + + @param This Protocol instance pointer. + @param MediaId Id of the media, changes every time the media is replaced. + @param Offset The starting byte offset to read from + @param BufferSize Size of Buffer + @param Buffer Buffer containing read data + + @retval EFI_SUCCESS The data was read correctly from the device. + @retval EFI_DEVICE_ERROR The device reported an error while performing the read. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_INVALID_PARAMETER The read request contains device addresses that are not + valid for the device. + +**/ +EFI_STATUS +EFIAPI +Ring3DiskIoRead ( + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + +/** + Writes a specified number of bytes to a device. + + @param This Indicates a pointer to the calling context. + @param MediaId ID of the medium to be written. + @param Offset The starting byte offset on the logical block I/O device to write. + @param BufferSize The size in bytes of Buffer. The number of bytes to write to the device. + @param Buffer A pointer to the buffer containing the data to be written. + + @retval EFI_SUCCESS The data was written correctly to the device. + @retval EFI_WRITE_PROTECTED The device can not be written to. + @retval EFI_DEVICE_ERROR The device reported an error while performing the write. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_INVALID_PARAMETER The write request contains device addresses that are not + valid for the device. + +**/ +EFI_STATUS +EFIAPI +Ring3DiskIoWrite ( + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +/** + Returns the current time and date information, and the time-keeping capabilities + of the hardware platform. + + @param[out] Time A pointer to storage to receive a snapshot of the current time. + @param[out] Capabilities An optional pointer to a buffer to receive the real time clock + device's capabilities. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER Time is NULL. + @retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error. + +**/ +EFI_STATUS +EFIAPI +Ring3GetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ); + +/** + Sets the current local time and date information. + + @param[in] Time A pointer to the current time. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER A time field is out of range. + @retval EFI_DEVICE_ERROR The time could not be set due due to hardware error. + +**/ +EFI_STATUS +EFIAPI +Ring3SetTime ( + IN EFI_TIME *Time + ); + +/** + Returns the current wakeup alarm clock setting. + + @param[out] Enabled Indicates if the alarm is currently enabled or disabled. + @param[out] Pending Indicates if the alarm signal is pending and requires acknowledgement. + @param[out] Time The current alarm setting. + + @retval EFI_SUCCESS The alarm settings were returned. + @retval EFI_INVALID_PARAMETER Enabled is NULL. + @retval EFI_INVALID_PARAMETER Pending is NULL. + @retval EFI_INVALID_PARAMETER Time is NULL. + @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error. + @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. + +**/ +EFI_STATUS +EFIAPI +Ring3GetWakeupTime ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ); + +/** + Sets the system wakeup alarm clock time. + + @param[in] Enable Enable or disable the wakeup alarm. + @param[in] Time If Enable is TRUE, the time to set the wakeup alarm for. + If Enable is FALSE, then this parameter is optional, and may be NULL. + + @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If + Enable is FALSE, then the wakeup alarm was disabled. + @retval EFI_INVALID_PARAMETER A time field is out of range. + @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error. + @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. + +**/ +EFI_STATUS +EFIAPI +Ring3SetWakeupTime ( + IN BOOLEAN Enable, + IN EFI_TIME *Time OPTIONAL + ); + +/** + Changes the runtime addressing mode of EFI firmware from physical to virtual. + + @param[in] MemoryMapSize The size in bytes of VirtualMap. + @param[in] DescriptorSize The size in bytes of an entry in the VirtualMap. + @param[in] DescriptorVersion The version of the structure entries in VirtualMap. + @param[in] VirtualMap An array of memory descriptors which contain new virtual + address mapping information for all runtime ranges. + + @retval EFI_SUCCESS The virtual address map has been applied. + @retval EFI_UNSUPPORTED EFI firmware is not at runtime, or the EFI firmware is already in + virtual address mapped mode. + @retval EFI_INVALID_PARAMETER DescriptorSize or DescriptorVersion is invalid. + @retval EFI_NO_MAPPING A virtual address was not supplied for a range in the memory + map that requires a mapping. + @retval EFI_NOT_FOUND A virtual address was supplied for an address that is not found + in the memory map. + +**/ +EFI_STATUS +EFIAPI +Ring3SetVirtualAddressMap ( + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize, + IN UINT32 DescriptorVersion, + IN EFI_MEMORY_DESCRIPTOR *VirtualMap + ); + +/** + Determines the new virtual address that is to be used on subsequent memory accesses. + + @param[in] DebugDisposition Supplies type information for the pointer being converted. + @param[in, out] Address A pointer to a pointer that is to be fixed to be the value needed + for the new virtual address mappings being applied. + + @retval EFI_SUCCESS The pointer pointed to by Address was modified. + @retval EFI_INVALID_PARAMETER 1) Address is NULL. + 2) *Address is NULL and DebugDisposition does + not have the EFI_OPTIONAL_PTR bit set. + @retval EFI_NOT_FOUND The pointer pointed to by Address was not found to be part + of the current memory map. This is normally fatal. + +**/ +EFI_STATUS +EFIAPI +Ring3ConvertPointer ( + IN UINTN DebugDisposition, + IN OUT VOID **Address + ); + +/** + Returns the value of a variable. + + @param[in] VariableName A Null-terminated string that is the name of the vendor's + variable. + @param[in] VendorGuid A unique identifier for the vendor. + @param[out] Attributes If not NULL, a pointer to the memory location to return the + attributes bitmask for the variable. + @param[in, out] DataSize On input, the size in bytes of the return Data buffer. + On output the size of data returned in Data. + @param[out] Data The buffer to return the contents of the variable. May be NULL + with a zero DataSize in order to determine the size buffer needed. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND The variable was not found. + @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. + @retval EFI_INVALID_PARAMETER VariableName is NULL. + @retval EFI_INVALID_PARAMETER VendorGuid is NULL. + @retval EFI_INVALID_PARAMETER DataSize is NULL. + @retval EFI_INVALID_PARAMETER The DataSize is not too small and Data is NULL. + @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. + @retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure. + +**/ +EFI_STATUS +EFIAPI +Ring3GetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data OPTIONAL + ); + +/** + Enumerates the current variable names. + + @param[in, out] VariableNameSize The size of the VariableName buffer. The size must be large + enough to fit input string supplied in VariableName buffer. + @param[in, out] VariableName On input, supplies the last VariableName that was returned + by GetNextVariableName(). On output, returns the Nullterminated + string of the current variable. + @param[in, out] VendorGuid On input, supplies the last VendorGuid that was returned by + GetNextVariableName(). On output, returns the + VendorGuid of the current variable. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND The next variable was not found. + @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result. + VariableNameSize has been updated with the size needed to complete the request. + @retval EFI_INVALID_PARAMETER VariableNameSize is NULL. + @retval EFI_INVALID_PARAMETER VariableName is NULL. + @retval EFI_INVALID_PARAMETER VendorGuid is NULL. + @retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and + GUID of an existing variable. + @retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of + the input VariableName buffer. + @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. + +**/ +EFI_STATUS +EFIAPI +Ring3GetNextVariableName ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid + ); + +/** + Sets the value of a variable. + + @param[in] VariableName A Null-terminated string that is the name of the vendor's variable. + Each VariableName is unique for each VendorGuid. VariableName must + contain 1 or more characters. If VariableName is an empty string, + then EFI_INVALID_PARAMETER is returned. + @param[in] VendorGuid A unique identifier for the vendor. + @param[in] Attributes Attributes bitmask to set for the variable. + @param[in] DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE or + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero + causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is + set, then a SetVariable() call with a DataSize of zero will not cause any change to + the variable value (the timestamp associated with the variable may be updated however + even if no new data value is provided,see the description of the + EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not + be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated). + @param[in] Data The contents for the variable. + + @retval EFI_SUCCESS The firmware has successfully stored the variable and its data as + defined by the Attributes. + @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied, or the + DataSize exceeds the maximum allowed. + @retval EFI_INVALID_PARAMETER VariableName is an empty string. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. + @retval EFI_WRITE_PROTECTED The variable in question is read-only. + @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted. + @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, + but the AuthInfo does NOT pass the validation check carried out by the firmware. + + @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. + +**/ +EFI_STATUS +EFIAPI +Ring3SetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ); + +/** + Returns the next high 32 bits of the platform's monotonic counter. + + @param[out] HighCount The pointer to returned value. + + @retval EFI_SUCCESS The next high monotonic count was returned. + @retval EFI_INVALID_PARAMETER HighCount is NULL. + @retval EFI_DEVICE_ERROR The device is not functioning properly. + +**/ +EFI_STATUS +EFIAPI +Ring3GetNextHighMonotonicCount ( + OUT UINT32 *HighCount + ); + +/** + Resets the entire platform. + + @param[in] ResetType The type of reset to perform. + @param[in] ResetStatus The status code for the reset. + @param[in] DataSize The size, in bytes, of ResetData. + @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or + EfiResetShutdown the data buffer starts with a Null-terminated + string, optionally followed by additional binary data. + The string is a description that the caller may use to further + indicate the reason for the system reset. + For a ResetType of EfiResetPlatformSpecific the data buffer + also starts with a Null-terminated string that is followed + by an EFI_GUID that describes the specific type of reset to perform. +**/ +VOID +EFIAPI +Ring3ResetSystem ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ); + +/** + Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended + consumption, the firmware may process the capsule immediately. If the payload should persist + across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities must + be passed into ResetSystem() and will cause the capsule to be processed by the firmware as + part of the reset process. + + @param[in] CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules + being passed into update capsule. + @param[in] CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in + CaspuleHeaderArray. + @param[in] ScatterGatherList Physical pointer to a set of + EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the + location in physical memory of a set of capsules. + + @retval EFI_SUCCESS Valid capsule was passed. If + CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the + capsule has been successfully processed by the firmware. + @retval EFI_INVALID_PARAMETER CapsuleSize is NULL, or an incompatible set of flags were + set in the capsule header. + @retval EFI_INVALID_PARAMETER CapsuleCount is 0. + @retval EFI_DEVICE_ERROR The capsule update was started, but failed due to a device error. + @retval EFI_UNSUPPORTED The capsule type is not supported on this platform. + @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule + is compatible with this platform but is not capable of being submitted or processed + in runtime. The caller may resubmit the capsule prior to ExitBootServices(). + @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates + the capsule is compatible with this platform but there are insufficient resources to process. + +**/ +EFI_STATUS +EFIAPI +Ring3UpdateCapsule ( + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL + ); + +/** + Returns if the capsule can be supported via UpdateCapsule(). + + @param[in] CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules + being passed into update capsule. + @param[in] CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in + CaspuleHeaderArray. + @param[out] MaxiumCapsuleSize On output the maximum size that UpdateCapsule() can + support as an argument to UpdateCapsule() via + CapsuleHeaderArray and ScatterGatherList. + @param[out] ResetType Returns the type of reset required for the capsule update. + + @retval EFI_SUCCESS Valid answer returned. + @retval EFI_UNSUPPORTED The capsule type is not supported on this platform, and + MaximumCapsuleSize and ResetType are undefined. + @retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL. + @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule + is compatible with this platform but is not capable of being submitted or processed + in runtime. The caller may resubmit the capsule prior to ExitBootServices(). + @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates + the capsule is compatible with this platform but there are insufficient resources to process. + +**/ +EFI_STATUS +EFIAPI +Ring3QueryCapsuleCapabilities ( + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + OUT UINT64 *MaximumCapsuleSize, + OUT EFI_RESET_TYPE *ResetType + ); + +/** + Returns information about the EFI variables. + + @param[in] Attributes Attributes bitmask to specify the type of variables on + which to return information. + @param[out] MaximumVariableStorageSize On output the maximum size of the storage space + available for the EFI variables associated with the + attributes specified. + @param[out] RemainingVariableStorageSize Returns the remaining size of the storage space + available for the EFI variables associated with the + attributes specified. + @param[out] MaximumVariableSize Returns the maximum size of the individual EFI + variables associated with the attributes specified. + + @retval EFI_SUCCESS Valid answer returned. + @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied + @retval EFI_UNSUPPORTED The attribute is not supported on this platform, and the + MaximumVariableStorageSize, + RemainingVariableStorageSize, MaximumVariableSize + are undefined. + +**/ +EFI_STATUS +EFIAPI +Ring3QueryVariableInfo ( + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize + ); + +/** + Performs a case-insensitive comparison of two Null-terminated strings. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param Str1 A pointer to a Null-terminated string. + @param Str2 A pointer to a Null-terminated string. + + @retval 0 Str1 is equivalent to Str2. + @retval >0 Str1 is lexically greater than Str2. + @retval <0 Str1 is lexically less than Str2. + +**/ +INTN +EFIAPI +Ring3UnicodeStriColl ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *Str1, + IN CHAR16 *Str2 + ); + +/** + Performs a case-insensitive comparison of a Null-terminated + pattern string and a Null-terminated string. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param String A pointer to a Null-terminated string. + @param Pattern A pointer to a Null-terminated pattern string. + + @retval TRUE Pattern was found in String. + @retval FALSE Pattern was not found in String. + +**/ +BOOLEAN +EFIAPI +Ring3UnicodeMetaiMatch ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ); + +/** + Converts all the characters in a Null-terminated string to + lower case characters. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param String A pointer to a Null-terminated string. + +**/ +VOID +EFIAPI +Ring3UnicodeStrLwr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ); + +/** + Converts all the characters in a Null-terminated string to upper + case characters. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param String A pointer to a Null-terminated string. + +**/ +VOID +EFIAPI +Ring3UnicodeStrUpr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ); + +/** + Converts an 8.3 FAT file name in an OEM character set to a Null-terminated + string. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param FatSize The size of the string Fat in bytes. + @param Fat A pointer to a Null-terminated string that contains an 8.3 file + name using an 8-bit OEM character set. + @param String A pointer to a Null-terminated string. The string must + be allocated in advance to hold FatSize characters. + +**/ +VOID +EFIAPI +Ring3UnicodeFatToStr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String + ); + +/** + Converts a Null-terminated string to legal characters in a FAT + filename using an OEM character set. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param String A pointer to a Null-terminated string. + @param FatSize The size of the string Fat in bytes. + @param Fat A pointer to a string that contains the converted version of + String using legal FAT characters from an OEM character set. + + @retval TRUE One or more conversions failed and were substituted with '_' + @retval FALSE None of the conversions failed. + +**/ +BOOLEAN +EFIAPI +Ring3UnicodeStrToFat ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat + ); diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c index 9731dedb67..7c01109a3e 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c @@ -1,210 +1,210 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include "Ring3.h" - -EFI_STATUS -EFIAPI -Ring3BlockIoReset ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ) -{ - return SysCall ( - SysCallBlockIoReset, - This, - ExtendedVerification - ); -} - -EFI_STATUS -EFIAPI -Ring3BlockIoRead ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - return SysCall ( - SysCallBlockIoRead, - This, - MediaId, - BufferSize, - Buffer, - Lba - ); -} - -EFI_STATUS -EFIAPI -Ring3BlockIoWrite ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - return SysCall ( - SysCallBlockIoWrite, - This, - MediaId, - BufferSize, - Buffer, - Lba - ); -} - -EFI_STATUS -EFIAPI -Ring3BlockIoFlush ( - IN EFI_BLOCK_IO_PROTOCOL *This - ) -{ - return SysCall ( - SysCallBlockIoFlush, - This - ); -} - -EFI_STATUS -EFIAPI -Ring3DiskIoRead ( - IN EFI_DISK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Offset, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - return SysCall ( - SysCallDiskIoRead, - This, - MediaId, - BufferSize, - Buffer, - Offset - ); -} - -EFI_STATUS -EFIAPI -Ring3DiskIoWrite ( - IN EFI_DISK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Offset, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - return SysCall ( - SysCallDiskIoWrite, - This, - MediaId, - BufferSize, - Buffer, - Offset - ); -} - -INTN -EFIAPI -Ring3UnicodeStriColl ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *Str1, - IN CHAR16 *Str2 - ) -{ - return (INTN)SysCall ( - SysCallUnicodeStriColl, - This, - Str1, - Str2 - ); -} - -BOOLEAN -EFIAPI -Ring3UnicodeMetaiMatch ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *String, - IN CHAR16 *Pattern - ) -{ - return (BOOLEAN)SysCall ( - SysCallUnicodeMetaiMatch, - This, - String, - Pattern - ); -} - -VOID -EFIAPI -Ring3UnicodeStrLwr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str - ) -{ - SysCall ( - SysCallUnicodeStrLwr, - This, - Str - ); -} - -VOID -EFIAPI -Ring3UnicodeStrUpr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str - ) -{ - SysCall ( - SysCallUnicodeStrUpr, - This, - Str - ); -} - -VOID -EFIAPI -Ring3UnicodeFatToStr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN UINTN FatSize, - IN CHAR8 *Fat, - OUT CHAR16 *String - ) -{ - SysCall ( - SysCallUnicodeFatToStr, - This, - FatSize, - Fat, - String - ); -} - -BOOLEAN -EFIAPI -Ring3UnicodeStrToFat ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *String, - IN UINTN FatSize, - OUT CHAR8 *Fat - ) -{ - return (BOOLEAN)SysCall ( - SysCallUnicodeStrToFat, - This, - String, - FatSize, - Fat - ); -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "Ring3.h" + +EFI_STATUS +EFIAPI +Ring3BlockIoReset ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + return SysCall ( + SysCallBlockIoReset, + This, + ExtendedVerification + ); +} + +EFI_STATUS +EFIAPI +Ring3BlockIoRead ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + return SysCall ( + SysCallBlockIoRead, + This, + MediaId, + BufferSize, + Buffer, + Lba + ); +} + +EFI_STATUS +EFIAPI +Ring3BlockIoWrite ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + return SysCall ( + SysCallBlockIoWrite, + This, + MediaId, + BufferSize, + Buffer, + Lba + ); +} + +EFI_STATUS +EFIAPI +Ring3BlockIoFlush ( + IN EFI_BLOCK_IO_PROTOCOL *This + ) +{ + return SysCall ( + SysCallBlockIoFlush, + This + ); +} + +EFI_STATUS +EFIAPI +Ring3DiskIoRead ( + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + return SysCall ( + SysCallDiskIoRead, + This, + MediaId, + BufferSize, + Buffer, + Offset + ); +} + +EFI_STATUS +EFIAPI +Ring3DiskIoWrite ( + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + return SysCall ( + SysCallDiskIoWrite, + This, + MediaId, + BufferSize, + Buffer, + Offset + ); +} + +INTN +EFIAPI +Ring3UnicodeStriColl ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *Str1, + IN CHAR16 *Str2 + ) +{ + return (INTN)SysCall ( + SysCallUnicodeStriColl, + This, + Str1, + Str2 + ); +} + +BOOLEAN +EFIAPI +Ring3UnicodeMetaiMatch ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ) +{ + return (BOOLEAN)SysCall ( + SysCallUnicodeMetaiMatch, + This, + String, + Pattern + ); +} + +VOID +EFIAPI +Ring3UnicodeStrLwr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ) +{ + SysCall ( + SysCallUnicodeStrLwr, + This, + Str + ); +} + +VOID +EFIAPI +Ring3UnicodeStrUpr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ) +{ + SysCall ( + SysCallUnicodeStrUpr, + This, + Str + ); +} + +VOID +EFIAPI +Ring3UnicodeFatToStr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String + ) +{ + SysCall ( + SysCallUnicodeFatToStr, + This, + FatSize, + Fat, + String + ); +} + +BOOLEAN +EFIAPI +Ring3UnicodeStrToFat ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat + ) +{ + return (BOOLEAN)SysCall ( + SysCallUnicodeStrToFat, + This, + String, + FatSize, + Fat + ); +} diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index 0dab6fc79e..f21bf6c1aa 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -1,789 +1,789 @@ -/** @file - This driver constructs Ring 3 wrappers for the EFI_BOOT_SERVICES. - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include - -#include - -#include -#include -#include - -#include "Ring3.h" - -BOOLEAN mOnGuarding = FALSE; - -STATIC -EFI_STATUS -EFIAPI -FixInterface ( - IN EFI_GUID *Protocol, - IN OUT VOID **Interface - ) -{ - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EFI_DISK_IO_PROTOCOL *DiskIo; - EFI_DEVICE_PATH_UTILITIES_PROTOCOL *DevicePath; - EFI_UNICODE_COLLATION_PROTOCOL *Unicode; - - ASSERT (Protocol != NULL); - ASSERT (Interface != NULL); - - if (CompareGuid (Protocol, &gEfiDevicePathProtocolGuid)) { - - } else if (CompareGuid (Protocol, &gEfiLoadedImageProtocolGuid)) { - - LoadedImage = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface; - - // TODO: Copy User changes to Core? Resembles InstallMultipleProtocolInterfaces(). - - LoadedImage->Unload = NULL; - - } else if (CompareGuid (Protocol, &gEfiBlockIoProtocolGuid)) { - - BlockIo = (EFI_BLOCK_IO_PROTOCOL *)*Interface; - - BlockIo->Reset = Ring3BlockIoReset; - BlockIo->ReadBlocks = Ring3BlockIoRead; - BlockIo->WriteBlocks = Ring3BlockIoWrite; - BlockIo->FlushBlocks = Ring3BlockIoFlush; - - } else if (CompareGuid (Protocol, &gEfiDiskIoProtocolGuid)) { - - DiskIo = (EFI_DISK_IO_PROTOCOL *)*Interface; - - DiskIo->ReadDisk = Ring3DiskIoRead; - DiskIo->WriteDisk = Ring3DiskIoWrite; - - } else if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) { - DevicePath = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface; - - DevicePath->GetDevicePathSize = NULL; - DevicePath->DuplicateDevicePath = NULL; - DevicePath->AppendDevicePath = NULL; - DevicePath->AppendDeviceNode = NULL; - DevicePath->AppendDevicePathInstance = NULL; - DevicePath->GetNextDevicePathInstance = NULL; - DevicePath->IsDevicePathMultiInstance = NULL; - DevicePath->CreateDeviceNode = NULL; - - } else if (CompareGuid (Protocol, &gEfiUnicodeCollationProtocolGuid)) { - Unicode = (EFI_UNICODE_COLLATION_PROTOCOL *)*Interface; - - Unicode->StriColl = Ring3UnicodeStriColl; - Unicode->MetaiMatch = Ring3UnicodeMetaiMatch; - Unicode->StrLwr = Ring3UnicodeStrLwr; - Unicode->StrUpr = Ring3UnicodeStrUpr; - Unicode->FatToStr = Ring3UnicodeFatToStr; - Unicode->StrToFat = Ring3UnicodeStrToFat; - - } else { - return EFI_UNSUPPORTED; - } - - return EFI_SUCCESS; -} - -EFI_TPL -EFIAPI -Ring3RaiseTpl ( - IN EFI_TPL NewTpl - ) -{ - return (EFI_TPL)SysCall ( - SysCallRaiseTpl, - NewTpl - ); -} - -VOID -EFIAPI -Ring3RestoreTpl ( - IN EFI_TPL NewTpl - ) -{ - SysCall ( - SysCallRestoreTpl, - NewTpl - ); -} - -EFI_STATUS -EFIAPI -Ring3AllocatePages ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, - IN OUT EFI_PHYSICAL_ADDRESS *Memory - ) -{ - EFI_STATUS Status; - - Status = SysCall ( - SysCallAllocatePages, - Type, - MemoryType, - NumberOfPages, - Memory - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate %d pages.\n", NumberOfPages)); - } - - return Status; -} - -EFI_STATUS -EFIAPI -Ring3FreePages ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages - ) -{ - EFI_STATUS Status; - - Status = SysCall ( - SysCallFreePages, - NumberOfPages, - Memory - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to free %d pages.\n", NumberOfPages)); - } - - return Status; -} - -EFI_STATUS -EFIAPI -Ring3GetMemoryMap ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: GetMemoryMap is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3CreateEvent ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, - IN VOID *NotifyContext OPTIONAL, - OUT EFI_EVENT *Event - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: CreateEvent is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3SetTimer ( - IN EFI_EVENT UserEvent, - IN EFI_TIMER_DELAY Type, - IN UINT64 TriggerTime - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: SetTimer is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3WaitForEvent ( - IN UINTN NumberOfEvents, - IN EFI_EVENT *UserEvents, - OUT UINTN *UserIndex - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: WaitForEvent is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3SignalEvent ( - IN EFI_EVENT UserEvent - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: SignalEvent is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3CloseEvent ( - IN EFI_EVENT UserEvent - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: CloseEvent is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3CheckEvent ( - IN EFI_EVENT UserEvent - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: CheckEvent is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3InstallProtocolInterface ( - IN OUT EFI_HANDLE *UserHandle, - IN EFI_GUID *Protocol, - IN EFI_INTERFACE_TYPE InterfaceType, - IN VOID *Interface - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: InstallProtocolInterface is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3ReinstallProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN VOID *OldInterface, - IN VOID *NewInterface - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: ReinstallProtocolInterface is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3UninstallProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN VOID *Interface - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: UninstallProtocolInterface is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3HandleProtocol ( - IN EFI_HANDLE CoreUserHandle, - IN EFI_GUID *Protocol, - OUT VOID **Interface - ) -{ - EFI_STATUS Status; - - Status = SysCall ( - SysCallHandleProtocol, - CoreUserHandle, - Protocol, - Interface - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to get handle of protocol %g - %r\n", Protocol, Status)); - return Status; - } - - return FixInterface (Protocol, Interface); -} - -EFI_STATUS -EFIAPI -Ring3RegisterProtocolNotify ( - IN EFI_GUID *Protocol, - IN EFI_EVENT Event, - OUT VOID **Registration - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: RegisterProtocolNotify is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3LocateHandle ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *BufferSize, - OUT EFI_HANDLE *Buffer - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: LocateHandle is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3LocateDevicePath ( - IN EFI_GUID *Protocol, - IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, - OUT EFI_HANDLE *Device - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: LocateDevicePath is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3InstallConfigurationTable ( - IN EFI_GUID *Guid, - IN VOID *Table - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: InstallConfigurationTable is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3LoadImage ( - IN BOOLEAN BootPolicy, - IN EFI_HANDLE ParentImageHandle, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN VOID *SourceBuffer OPTIONAL, - IN UINTN SourceSize, - OUT EFI_HANDLE *ImageHandle - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: LoadImage is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3StartImage ( - IN EFI_HANDLE ImageHandle, - OUT UINTN *ExitDataSize, - OUT CHAR16 **ExitData OPTIONAL - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: StartImage is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3Exit ( - IN EFI_HANDLE ImageHandle, - IN EFI_STATUS Status, - IN UINTN ExitDataSize, - IN CHAR16 *ExitData OPTIONAL - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: Exit is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3UnloadImage ( - IN EFI_HANDLE ImageHandle - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: UnloadImage is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3ExitBootServices ( - IN EFI_HANDLE ImageHandle, - IN UINTN MapKey - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: ExitBootServices is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3GetNextMonotonicCount ( - OUT UINT64 *Count - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: GetNextMonotonicCount is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3Stall ( - IN UINTN Microseconds - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: Stall is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3SetWatchdogTimer ( - IN UINTN Timeout, - IN UINT64 WatchdogCode, - IN UINTN DataSize, - IN CHAR16 *WatchdogData OPTIONAL - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: SetWatchdogTimer is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3ConnectController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE *DriverImageHandle OPTIONAL, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, - IN BOOLEAN Recursive - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: ConnectController is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3DisconnectController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE DriverImageHandle OPTIONAL, - IN EFI_HANDLE ChildHandle OPTIONAL - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: DisconnectController is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3OpenProtocol ( - IN EFI_HANDLE CoreUserHandle, - IN EFI_GUID *Protocol, - OUT VOID **Interface OPTIONAL, - IN EFI_HANDLE CoreImageHandle, - IN EFI_HANDLE CoreControllerHandle, - IN UINT32 Attributes - ) -{ - EFI_STATUS Status; - - Status = SysCall ( - SysCallOpenProtocol, - CoreUserHandle, - Protocol, - Interface, - CoreImageHandle, - CoreControllerHandle, - Attributes - ); - if (EFI_ERROR (Status)) { - return Status; - } - - return (Interface != NULL) ? FixInterface (Protocol, Interface) : Status; -} - -EFI_STATUS -EFIAPI -Ring3CloseProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN EFI_HANDLE AgentHandle, - IN EFI_HANDLE ControllerHandle - ) -{ - return SysCall ( - SysCallCloseProtocol, - UserHandle, - Protocol, - AgentHandle, - ControllerHandle - ); -} - -EFI_STATUS -EFIAPI -Ring3OpenProtocolInformation ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, - OUT UINTN *EntryCount - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: OpenProtocolInformation is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3ProtocolsPerHandle ( - IN EFI_HANDLE UserHandle, - OUT EFI_GUID ***ProtocolBuffer, - OUT UINTN *ProtocolBufferCount - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: ProtocolsPerHandle is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3LocateHandleBuffer ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *NumberHandles, - OUT EFI_HANDLE **Buffer - ) -{ - EFI_STATUS Status; - EFI_STATUS StatusBS; - VOID *Pool; - UINTN PoolSize; - - StatusBS = SysCall ( - SysCallLocateHandleBuffer, - SearchType, - Protocol, - SearchKey, - NumberHandles, - Buffer - ); - - if ((!EFI_ERROR (StatusBS)) && (NumberHandles != NULL) && (*NumberHandles != 0) - && (Buffer != NULL) && (*Buffer != NULL)) { - PoolSize = *NumberHandles * sizeof (EFI_HANDLE *); - - Status = CoreAllocatePool (EfiRing3MemoryType, PoolSize, &Pool); - if (EFI_ERROR (Status)) { - return Status; - } - - CopyMem (Pool, *Buffer, PoolSize); - - Status = Ring3FreePages ( - (EFI_PHYSICAL_ADDRESS)(UINTN)*Buffer, - EFI_SIZE_TO_PAGES (PoolSize) - ); - if (EFI_ERROR (Status)) { - return Status; - } - - *Buffer = Pool; - } - - return StatusBS; -} - -EFI_STATUS -EFIAPI -Ring3LocateProtocol ( - IN EFI_GUID *Protocol, - IN VOID *CoreRegistration OPTIONAL, - OUT VOID **Interface - ) -{ - EFI_STATUS Status; - - Status = SysCall ( - SysCallLocateProtocol, - Protocol, - CoreRegistration, - Interface - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to loacate protocol %g\n", Protocol)); - return Status; - } - - return FixInterface (Protocol, Interface); -} - -EFI_STATUS -EFIAPI -Ring3InstallMultipleProtocolInterfaces ( - IN OUT EFI_HANDLE *Handle, - ... - ) -{ - VA_LIST Marker; - VOID *Argument; - VOID *ArgList[MAX_LIST]; - UINTN Index; - - VA_START (Marker, Handle); - for (Index = 0; Index < MAX_LIST; ++Index) { - Argument = VA_ARG (Marker, VOID *); - ArgList[Index] = Argument; - - if (Argument == NULL) { - break; - } - } - VA_END (Marker); - - if (Index == MAX_LIST) { - DEBUG ((DEBUG_ERROR, "Ring3: Too many arguments\n")); - return EFI_INVALID_PARAMETER; - } - - return SysCall ( - SysCallInstallMultipleProtocolInterfaces, - Handle, - ArgList - ); -} - -EFI_STATUS -EFIAPI -Ring3UninstallMultipleProtocolInterfaces ( - IN EFI_HANDLE Handle, - ... - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: UninstallMultipleProtocolInterfaces is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3CalculateCrc32 ( - IN VOID *Data, - IN UINTN DataSize, - OUT UINT32 *Crc32 - ) -{ - return SysCall ( - SysCallCalculateCrc32, - Data, - DataSize, - Crc32 - ); -} - -EFI_STATUS -EFIAPI -Ring3CreateEventEx ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, - IN CONST VOID *NotifyContext OPTIONAL, - IN CONST EFI_GUID *EventGroup OPTIONAL, - OUT EFI_EVENT *Event - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: CreateEventEx is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -CoreUpdateProfile ( - IN EFI_PHYSICAL_ADDRESS CallerAddress, - IN MEMORY_PROFILE_ACTION Action, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool - IN VOID *Buffer, - IN CHAR8 *ActionString OPTIONAL - ) -{ - return EFI_SUCCESS; -} - -VOID -InstallMemoryAttributesTableOnMemoryAllocation ( - IN EFI_MEMORY_TYPE MemoryType - ) -{ - return; -} - -BOOLEAN -EFIAPI -IsMemoryGuarded ( - IN EFI_PHYSICAL_ADDRESS Address - ) -{ - return FALSE; -} - -VOID * -CoreAllocatePoolPagesI ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN NoPages, - IN UINTN Granularity, - IN BOOLEAN NeedGuard - ) -{ - EFI_PHYSICAL_ADDRESS Memory; - - Ring3AllocatePages (AllocateAnyPages, EfiRing3MemoryType, NoPages, &Memory); - - return (VOID *)(UINTN)Memory; -} - -VOID -CoreFreePoolPagesI ( - IN EFI_MEMORY_TYPE PoolType, - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NoPages - ) -{ - Ring3FreePages (Memory, NoPages); -} - -VOID -CoreFreePoolPagesWithGuard ( - IN EFI_MEMORY_TYPE PoolType, - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NoPages - ) -{ - CoreFreePoolPagesI (PoolType, Memory, NoPages); -} +/** @file + This driver constructs Ring 3 wrappers for the EFI_BOOT_SERVICES. + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include + +#include + +#include +#include +#include + +#include "Ring3.h" + +BOOLEAN mOnGuarding = FALSE; + +STATIC +EFI_STATUS +EFIAPI +FixInterface ( + IN EFI_GUID *Protocol, + IN OUT VOID **Interface + ) +{ + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_DEVICE_PATH_UTILITIES_PROTOCOL *DevicePath; + EFI_UNICODE_COLLATION_PROTOCOL *Unicode; + + ASSERT (Protocol != NULL); + ASSERT (Interface != NULL); + + if (CompareGuid (Protocol, &gEfiDevicePathProtocolGuid)) { + + } else if (CompareGuid (Protocol, &gEfiLoadedImageProtocolGuid)) { + + LoadedImage = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface; + + // TODO: Copy User changes to Core? Resembles InstallMultipleProtocolInterfaces(). + + LoadedImage->Unload = NULL; + + } else if (CompareGuid (Protocol, &gEfiBlockIoProtocolGuid)) { + + BlockIo = (EFI_BLOCK_IO_PROTOCOL *)*Interface; + + BlockIo->Reset = Ring3BlockIoReset; + BlockIo->ReadBlocks = Ring3BlockIoRead; + BlockIo->WriteBlocks = Ring3BlockIoWrite; + BlockIo->FlushBlocks = Ring3BlockIoFlush; + + } else if (CompareGuid (Protocol, &gEfiDiskIoProtocolGuid)) { + + DiskIo = (EFI_DISK_IO_PROTOCOL *)*Interface; + + DiskIo->ReadDisk = Ring3DiskIoRead; + DiskIo->WriteDisk = Ring3DiskIoWrite; + + } else if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) { + DevicePath = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface; + + DevicePath->GetDevicePathSize = NULL; + DevicePath->DuplicateDevicePath = NULL; + DevicePath->AppendDevicePath = NULL; + DevicePath->AppendDeviceNode = NULL; + DevicePath->AppendDevicePathInstance = NULL; + DevicePath->GetNextDevicePathInstance = NULL; + DevicePath->IsDevicePathMultiInstance = NULL; + DevicePath->CreateDeviceNode = NULL; + + } else if (CompareGuid (Protocol, &gEfiUnicodeCollationProtocolGuid)) { + Unicode = (EFI_UNICODE_COLLATION_PROTOCOL *)*Interface; + + Unicode->StriColl = Ring3UnicodeStriColl; + Unicode->MetaiMatch = Ring3UnicodeMetaiMatch; + Unicode->StrLwr = Ring3UnicodeStrLwr; + Unicode->StrUpr = Ring3UnicodeStrUpr; + Unicode->FatToStr = Ring3UnicodeFatToStr; + Unicode->StrToFat = Ring3UnicodeStrToFat; + + } else { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +EFI_TPL +EFIAPI +Ring3RaiseTpl ( + IN EFI_TPL NewTpl + ) +{ + return (EFI_TPL)SysCall ( + SysCallRaiseTpl, + NewTpl + ); +} + +VOID +EFIAPI +Ring3RestoreTpl ( + IN EFI_TPL NewTpl + ) +{ + SysCall ( + SysCallRestoreTpl, + NewTpl + ); +} + +EFI_STATUS +EFIAPI +Ring3AllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NumberOfPages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ) +{ + EFI_STATUS Status; + + Status = SysCall ( + SysCallAllocatePages, + Type, + MemoryType, + NumberOfPages, + Memory + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate %d pages.\n", NumberOfPages)); + } + + return Status; +} + +EFI_STATUS +EFIAPI +Ring3FreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ) +{ + EFI_STATUS Status; + + Status = SysCall ( + SysCallFreePages, + NumberOfPages, + Memory + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to free %d pages.\n", NumberOfPages)); + } + + return Status; +} + +EFI_STATUS +EFIAPI +Ring3GetMemoryMap ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetMemoryMap is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3CreateEvent ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN VOID *NotifyContext OPTIONAL, + OUT EFI_EVENT *Event + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: CreateEvent is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SetTimer ( + IN EFI_EVENT UserEvent, + IN EFI_TIMER_DELAY Type, + IN UINT64 TriggerTime + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SetTimer is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3WaitForEvent ( + IN UINTN NumberOfEvents, + IN EFI_EVENT *UserEvents, + OUT UINTN *UserIndex + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: WaitForEvent is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SignalEvent ( + IN EFI_EVENT UserEvent + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SignalEvent is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3CloseEvent ( + IN EFI_EVENT UserEvent + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: CloseEvent is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3CheckEvent ( + IN EFI_EVENT UserEvent + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: CheckEvent is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3InstallProtocolInterface ( + IN OUT EFI_HANDLE *UserHandle, + IN EFI_GUID *Protocol, + IN EFI_INTERFACE_TYPE InterfaceType, + IN VOID *Interface + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: InstallProtocolInterface is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3ReinstallProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN VOID *OldInterface, + IN VOID *NewInterface + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: ReinstallProtocolInterface is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3UninstallProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN VOID *Interface + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: UninstallProtocolInterface is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3HandleProtocol ( + IN EFI_HANDLE CoreUserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface + ) +{ + EFI_STATUS Status; + + Status = SysCall ( + SysCallHandleProtocol, + CoreUserHandle, + Protocol, + Interface + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to get handle of protocol %g - %r\n", Protocol, Status)); + return Status; + } + + return FixInterface (Protocol, Interface); +} + +EFI_STATUS +EFIAPI +Ring3RegisterProtocolNotify ( + IN EFI_GUID *Protocol, + IN EFI_EVENT Event, + OUT VOID **Registration + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: RegisterProtocolNotify is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3LocateHandle ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: LocateHandle is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3LocateDevicePath ( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, + OUT EFI_HANDLE *Device + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: LocateDevicePath is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3InstallConfigurationTable ( + IN EFI_GUID *Guid, + IN VOID *Table + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: InstallConfigurationTable is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3LoadImage ( + IN BOOLEAN BootPolicy, + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + OUT EFI_HANDLE *ImageHandle + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: LoadImage is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3StartImage ( + IN EFI_HANDLE ImageHandle, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: StartImage is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3Exit ( + IN EFI_HANDLE ImageHandle, + IN EFI_STATUS Status, + IN UINTN ExitDataSize, + IN CHAR16 *ExitData OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: Exit is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3UnloadImage ( + IN EFI_HANDLE ImageHandle + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: UnloadImage is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3ExitBootServices ( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: ExitBootServices is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3GetNextMonotonicCount ( + OUT UINT64 *Count + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetNextMonotonicCount is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3Stall ( + IN UINTN Microseconds + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: Stall is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SetWatchdogTimer ( + IN UINTN Timeout, + IN UINT64 WatchdogCode, + IN UINTN DataSize, + IN CHAR16 *WatchdogData OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SetWatchdogTimer is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3ConnectController ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE *DriverImageHandle OPTIONAL, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, + IN BOOLEAN Recursive + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: ConnectController is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3DisconnectController ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverImageHandle OPTIONAL, + IN EFI_HANDLE ChildHandle OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: DisconnectController is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3OpenProtocol ( + IN EFI_HANDLE CoreUserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface OPTIONAL, + IN EFI_HANDLE CoreImageHandle, + IN EFI_HANDLE CoreControllerHandle, + IN UINT32 Attributes + ) +{ + EFI_STATUS Status; + + Status = SysCall ( + SysCallOpenProtocol, + CoreUserHandle, + Protocol, + Interface, + CoreImageHandle, + CoreControllerHandle, + Attributes + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return (Interface != NULL) ? FixInterface (Protocol, Interface) : Status; +} + +EFI_STATUS +EFIAPI +Ring3CloseProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN EFI_HANDLE AgentHandle, + IN EFI_HANDLE ControllerHandle + ) +{ + return SysCall ( + SysCallCloseProtocol, + UserHandle, + Protocol, + AgentHandle, + ControllerHandle + ); +} + +EFI_STATUS +EFIAPI +Ring3OpenProtocolInformation ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, + OUT UINTN *EntryCount + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: OpenProtocolInformation is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3ProtocolsPerHandle ( + IN EFI_HANDLE UserHandle, + OUT EFI_GUID ***ProtocolBuffer, + OUT UINTN *ProtocolBufferCount + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: ProtocolsPerHandle is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3LocateHandleBuffer ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NumberHandles, + OUT EFI_HANDLE **Buffer + ) +{ + EFI_STATUS Status; + EFI_STATUS StatusBS; + VOID *Pool; + UINTN PoolSize; + + StatusBS = SysCall ( + SysCallLocateHandleBuffer, + SearchType, + Protocol, + SearchKey, + NumberHandles, + Buffer + ); + + if ((!EFI_ERROR (StatusBS)) && (NumberHandles != NULL) && (*NumberHandles != 0) + && (Buffer != NULL) && (*Buffer != NULL)) { + PoolSize = *NumberHandles * sizeof (EFI_HANDLE *); + + Status = CoreAllocatePool (EfiRing3MemoryType, PoolSize, &Pool); + if (EFI_ERROR (Status)) { + return Status; + } + + CopyMem (Pool, *Buffer, PoolSize); + + Status = Ring3FreePages ( + (EFI_PHYSICAL_ADDRESS)(UINTN)*Buffer, + EFI_SIZE_TO_PAGES (PoolSize) + ); + if (EFI_ERROR (Status)) { + return Status; + } + + *Buffer = Pool; + } + + return StatusBS; +} + +EFI_STATUS +EFIAPI +Ring3LocateProtocol ( + IN EFI_GUID *Protocol, + IN VOID *CoreRegistration OPTIONAL, + OUT VOID **Interface + ) +{ + EFI_STATUS Status; + + Status = SysCall ( + SysCallLocateProtocol, + Protocol, + CoreRegistration, + Interface + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to loacate protocol %g\n", Protocol)); + return Status; + } + + return FixInterface (Protocol, Interface); +} + +EFI_STATUS +EFIAPI +Ring3InstallMultipleProtocolInterfaces ( + IN OUT EFI_HANDLE *Handle, + ... + ) +{ + VA_LIST Marker; + VOID *Argument; + VOID *ArgList[MAX_LIST]; + UINTN Index; + + VA_START (Marker, Handle); + for (Index = 0; Index < MAX_LIST; ++Index) { + Argument = VA_ARG (Marker, VOID *); + ArgList[Index] = Argument; + + if (Argument == NULL) { + break; + } + } + VA_END (Marker); + + if (Index == MAX_LIST) { + DEBUG ((DEBUG_ERROR, "Ring3: Too many arguments\n")); + return EFI_INVALID_PARAMETER; + } + + return SysCall ( + SysCallInstallMultipleProtocolInterfaces, + Handle, + ArgList + ); +} + +EFI_STATUS +EFIAPI +Ring3UninstallMultipleProtocolInterfaces ( + IN EFI_HANDLE Handle, + ... + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: UninstallMultipleProtocolInterfaces is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3CalculateCrc32 ( + IN VOID *Data, + IN UINTN DataSize, + OUT UINT32 *Crc32 + ) +{ + return SysCall ( + SysCallCalculateCrc32, + Data, + DataSize, + Crc32 + ); +} + +EFI_STATUS +EFIAPI +Ring3CreateEventEx ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN CONST VOID *NotifyContext OPTIONAL, + IN CONST EFI_GUID *EventGroup OPTIONAL, + OUT EFI_EVENT *Event + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: CreateEventEx is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreUpdateProfile ( + IN EFI_PHYSICAL_ADDRESS CallerAddress, + IN MEMORY_PROFILE_ACTION Action, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool + IN VOID *Buffer, + IN CHAR8 *ActionString OPTIONAL + ) +{ + return EFI_SUCCESS; +} + +VOID +InstallMemoryAttributesTableOnMemoryAllocation ( + IN EFI_MEMORY_TYPE MemoryType + ) +{ + return; +} + +BOOLEAN +EFIAPI +IsMemoryGuarded ( + IN EFI_PHYSICAL_ADDRESS Address + ) +{ + return FALSE; +} + +VOID * +CoreAllocatePoolPagesI ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN NoPages, + IN UINTN Granularity, + IN BOOLEAN NeedGuard + ) +{ + EFI_PHYSICAL_ADDRESS Memory; + + Ring3AllocatePages (AllocateAnyPages, EfiRing3MemoryType, NoPages, &Memory); + + return (VOID *)(UINTN)Memory; +} + +VOID +CoreFreePoolPagesI ( + IN EFI_MEMORY_TYPE PoolType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ) +{ + Ring3FreePages (Memory, NoPages); +} + +VOID +CoreFreePoolPagesWithGuard ( + IN EFI_MEMORY_TYPE PoolType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ) +{ + CoreFreePoolPagesI (PoolType, Memory, NoPages); +} diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c index aabd1f1e26..e4e9af3299 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c @@ -1,194 +1,194 @@ -#include - -#include -#include - -#include "Ring3.h" - -EFI_STATUS -EFIAPI -Ring3GetTime ( - OUT EFI_TIME *Time, - OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: GetTime is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3SetTime ( - IN EFI_TIME *Time - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: SetTime is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3GetWakeupTime ( - OUT BOOLEAN *Enabled, - OUT BOOLEAN *Pending, - OUT EFI_TIME *Time - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: GetWakeupTime is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3SetWakeupTime ( - IN BOOLEAN Enable, - IN EFI_TIME *Time OPTIONAL - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: SetWakeupTime is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3SetVirtualAddressMap ( - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize, - IN UINT32 DescriptorVersion, - IN EFI_MEMORY_DESCRIPTOR *VirtualMap - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: SetVirtualAddressMap is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3ConvertPointer ( - IN UINTN DebugDisposition, - IN OUT VOID **Address - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: ConvertPointer is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3GetVariable ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - OUT UINT32 *Attributes OPTIONAL, - IN OUT UINTN *DataSize, - OUT VOID *Data OPTIONAL - ) -{ - return SysCall ( - SysCallGetVariable, - VariableName, - VendorGuid, - Attributes, - DataSize, - Data - ); -} - -EFI_STATUS -EFIAPI -Ring3GetNextVariableName ( - IN OUT UINTN *VariableNameSize, - IN OUT CHAR16 *VariableName, - IN OUT EFI_GUID *VendorGuid - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: GetNextVariableName is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3SetVariable ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - IN UINT32 Attributes, - IN UINTN DataSize, - IN VOID *Data - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: SetVariable is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3GetNextHighMonotonicCount ( - OUT UINT32 *HighCount - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: GetNextHighMonotonicCount is not supported\n")); - - return EFI_UNSUPPORTED; -} - -VOID -EFIAPI -Ring3ResetSystem ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN VOID *ResetData OPTIONAL - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: ResetSystem is not supported\n")); - - return; -} - -EFI_STATUS -EFIAPI -Ring3UpdateCapsule ( - IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, - IN UINTN CapsuleCount, - IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: UpdateCapsule is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3QueryCapsuleCapabilities ( - IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, - IN UINTN CapsuleCount, - OUT UINT64 *MaximumCapsuleSize, - OUT EFI_RESET_TYPE *ResetType - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: QueryCapsuleCapabilities is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3QueryVariableInfo ( - IN UINT32 Attributes, - OUT UINT64 *MaximumVariableStorageSize, - OUT UINT64 *RemainingVariableStorageSize, - OUT UINT64 *MaximumVariableSize - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: QueryVariableInfo is not supported\n")); - - return EFI_UNSUPPORTED; -} +#include + +#include +#include + +#include "Ring3.h" + +EFI_STATUS +EFIAPI +Ring3GetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetTime is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SetTime ( + IN EFI_TIME *Time + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SetTime is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3GetWakeupTime ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetWakeupTime is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SetWakeupTime ( + IN BOOLEAN Enable, + IN EFI_TIME *Time OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SetWakeupTime is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SetVirtualAddressMap ( + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize, + IN UINT32 DescriptorVersion, + IN EFI_MEMORY_DESCRIPTOR *VirtualMap + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SetVirtualAddressMap is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3ConvertPointer ( + IN UINTN DebugDisposition, + IN OUT VOID **Address + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: ConvertPointer is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3GetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data OPTIONAL + ) +{ + return SysCall ( + SysCallGetVariable, + VariableName, + VendorGuid, + Attributes, + DataSize, + Data + ); +} + +EFI_STATUS +EFIAPI +Ring3GetNextVariableName ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetNextVariableName is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SetVariable is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3GetNextHighMonotonicCount ( + OUT UINT32 *HighCount + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetNextHighMonotonicCount is not supported\n")); + + return EFI_UNSUPPORTED; +} + +VOID +EFIAPI +Ring3ResetSystem ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: ResetSystem is not supported\n")); + + return; +} + +EFI_STATUS +EFIAPI +Ring3UpdateCapsule ( + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: UpdateCapsule is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3QueryCapsuleCapabilities ( + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + OUT UINT64 *MaximumCapsuleSize, + OUT EFI_RESET_TYPE *ResetType + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: QueryCapsuleCapabilities is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3QueryVariableInfo ( + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: QueryVariableInfo is not supported\n")); + + return EFI_UNSUPPORTED; +} diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm index fc27a0bddc..d9c3d1162d 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm +++ b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm @@ -1,44 +1,44 @@ -;------------------------------------------------------------------------------ -; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -; SPDX-License-Identifier: BSD-3-Clause -;------------------------------------------------------------------------------ - -extern ASM_PFX(Ring3Call) - -DEFAULT REL -SECTION .text - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; SysCall ( -; IN UINT8 Type, -; ... -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(SysCall) -ASM_PFX(SysCall): - ; Save Type for CoreBootServices(). - mov r10, rcx - - ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. - syscall - ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. - - ret - -;------------------------------------------------------------------------------ -; VOID -; EFIAPI -; Ring3EntryPoint ( -; IN RING3_CALL_DATA *Data -; ); -; -; (rcx) RIP of Ring3EntryPoint saved for SYSRET in CallRing3(). -; (rdx) Data -;------------------------------------------------------------------------------ -global ASM_PFX(Ring3EntryPoint) -ASM_PFX(Ring3EntryPoint): - mov rcx, rdx - - call ASM_PFX(Ring3Call) +;------------------------------------------------------------------------------ +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause +;------------------------------------------------------------------------------ + +extern ASM_PFX(Ring3Call) + +DEFAULT REL +SECTION .text + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; SysCall ( +; IN UINT8 Type, +; ... +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(SysCall) +ASM_PFX(SysCall): + ; Save Type for CoreBootServices(). + mov r10, rcx + + ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. + syscall + ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. + + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; Ring3EntryPoint ( +; IN RING3_CALL_DATA *Data +; ); +; +; (rcx) RIP of Ring3EntryPoint saved for SYSRET in CallRing3(). +; (rdx) Data +;------------------------------------------------------------------------------ +global ASM_PFX(Ring3EntryPoint) +ASM_PFX(Ring3EntryPoint): + mov rcx, rdx + + call ASM_PFX(Ring3Call) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 0e705ddbce..cf6f098b7b 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -1,169 +1,169 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause -// -//------------------------------------------------------------------------------ - -#include - -.cpu cortex-a76 - -//------------------------------------------------------------------------------ -// EFI_STATUS -// EFIAPI -// CallInstallMultipleProtocolInterfaces ( -// IN EFI_HANDLE *Handle, -// IN VOID **ArgList, -// IN UINT32 ArgListSize, -// IN VOID *Function -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(CallInstallMultipleProtocolInterfaces) - stp x29, x30, [sp, #-0x10]! - mov x29, sp - // Save function input. - mov x9, x1 - mov x10, x2 - mov x11, x3 - // Prepare registers for call. - ldp x1, x2, [x9] - ldp x3, x4, [x9, #0x10] - ldp x5, x6, [x9, #0x20] - ldr x7, [x9, #0x30] - // Prepare stack for call. - cmp x10, #7 - b.le call - add x9, x9, x10, LSL #3 - sub x10, x10, #7 - tst x10, #1 - b.eq copy - // To align stack on 16 bytes. - add x9, x9, #0x8 - add x10, x10, #1 -copy: - ldp x12, x13, [x9, #-0x10]! - stp x12, x13, [sp, #-0x10]! - subs x10, x10, #2 - b.ne copy - -call: - blr x11 - - mov sp, x29 - ldp x29, x30, [sp] - add sp, sp, #0x10 - ret - -//------------------------------------------------------------------------------ -// EFI_STATUS -// EFIAPI -// CallRing3 ( -// IN RING3_CALL_DATA *Data -// ); -// -// (x0) Data -// (x1) gRing3CallStackTop -// (x2) gRing3EntryPoint -// (x3) gCoreSysCallStackTop -// (x4) &CoreSp -//------------------------------------------------------------------------------ -ASM_FUNC(ArmCallRing3) - // Save registers. - sub sp, sp, #0x100 - - stp q8, q9, [sp, #0xe0] - stp q10, q11, [sp, #0xc0] - stp q12, q13, [sp, #0xa0] - stp q14, q15, [sp, #0x80] - - stp xzr, x16, [sp, #0x70] - stp x17, x18, [sp, #0x60] - stp x19, x20, [sp, #0x50] - stp x21, x22, [sp, #0x40] - stp x23, x24, [sp, #0x30] - stp x25, x26, [sp, #0x20] - stp x27, x28, [sp, #0x10] - stp x29, x30, [sp] - // Disable interrupts. - msr daifset, #0xf - isb - // Prepare Ring3 SP and EntryPoint. - msr sp_el0, x1 - msr elr_el1, x2 - // Save Core SP and switch to CoreSysCall Stack. - mov x5, sp - str x5, [x4] - mov sp, x3 - // Copy PSTATE to SPSR. - mrs x1, nzcv - mrs x2, pan - orr x1, x1, x2 - // - // M[3:0], bits [3:0] AArch64 Exception level and selected Stack Pointer. - // 0b0000 - EL0. - // 0b0100 - EL1 with SP_EL0 (ELt). - // 0b0101 - EL1 with SP_EL1 (EL1h). - // - msr spsr_el1, x1 - isb - dsb sy - eret - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// ReturnToCore ( -// IN EFI_STATUS Status, -// IN UINTN CoreSp -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(ReturnToCore) - // Zero Exception Syndrome Register to prevent QEMU from random crashing. - msr esr_el1, xzr - msr spsr_el1, xzr - msr elr_el1, xzr - msr far_el1, xzr - // Switch to Core Stack. - mov sp, x1 - // Restore registers and Stack. - ldp q8, q9, [sp, #0xe0] - ldp q10, q11, [sp, #0xc0] - ldp q12, q13, [sp, #0xa0] - ldp q14, q15, [sp, #0x80] - - ldr x16, [sp, #0x78] - ldp x17, x18, [sp, #0x60] - ldp x19, x20, [sp, #0x50] - ldp x21, x22, [sp, #0x40] - ldp x23, x24, [sp, #0x30] - ldp x25, x26, [sp, #0x20] - ldp x27, x28, [sp, #0x10] - ldp x29, x30, [sp] - add sp, sp, #0x100 - // Enable interrupts. - msr daifclr, #0xf - isb - ret - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// ArmSetPan ( -// VOID -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(ArmSetPan) - msr pan, #1 - ret - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// ArmClearPan ( -// VOID -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(ArmClearPan) - msr pan, #0 - ret +//------------------------------------------------------------------------------ +// +// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +//------------------------------------------------------------------------------ + +#include + +.cpu cortex-a76 + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// CallInstallMultipleProtocolInterfaces ( +// IN EFI_HANDLE *Handle, +// IN VOID **ArgList, +// IN UINT32 ArgListSize, +// IN VOID *Function +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(CallInstallMultipleProtocolInterfaces) + stp x29, x30, [sp, #-0x10]! + mov x29, sp + // Save function input. + mov x9, x1 + mov x10, x2 + mov x11, x3 + // Prepare registers for call. + ldp x1, x2, [x9] + ldp x3, x4, [x9, #0x10] + ldp x5, x6, [x9, #0x20] + ldr x7, [x9, #0x30] + // Prepare stack for call. + cmp x10, #7 + b.le call + add x9, x9, x10, LSL #3 + sub x10, x10, #7 + tst x10, #1 + b.eq copy + // To align stack on 16 bytes. + add x9, x9, #0x8 + add x10, x10, #1 +copy: + ldp x12, x13, [x9, #-0x10]! + stp x12, x13, [sp, #-0x10]! + subs x10, x10, #2 + b.ne copy + +call: + blr x11 + + mov sp, x29 + ldp x29, x30, [sp] + add sp, sp, #0x10 + ret + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// CallRing3 ( +// IN RING3_CALL_DATA *Data +// ); +// +// (x0) Data +// (x1) gRing3CallStackTop +// (x2) gRing3EntryPoint +// (x3) gCoreSysCallStackTop +// (x4) &CoreSp +//------------------------------------------------------------------------------ +ASM_FUNC(ArmCallRing3) + // Save registers. + sub sp, sp, #0x100 + + stp q8, q9, [sp, #0xe0] + stp q10, q11, [sp, #0xc0] + stp q12, q13, [sp, #0xa0] + stp q14, q15, [sp, #0x80] + + stp xzr, x16, [sp, #0x70] + stp x17, x18, [sp, #0x60] + stp x19, x20, [sp, #0x50] + stp x21, x22, [sp, #0x40] + stp x23, x24, [sp, #0x30] + stp x25, x26, [sp, #0x20] + stp x27, x28, [sp, #0x10] + stp x29, x30, [sp] + // Disable interrupts. + msr daifset, #0xf + isb + // Prepare Ring3 SP and EntryPoint. + msr sp_el0, x1 + msr elr_el1, x2 + // Save Core SP and switch to CoreSysCall Stack. + mov x5, sp + str x5, [x4] + mov sp, x3 + // Copy PSTATE to SPSR. + mrs x1, nzcv + mrs x2, pan + orr x1, x1, x2 + // + // M[3:0], bits [3:0] AArch64 Exception level and selected Stack Pointer. + // 0b0000 - EL0. + // 0b0100 - EL1 with SP_EL0 (ELt). + // 0b0101 - EL1 with SP_EL1 (EL1h). + // + msr spsr_el1, x1 + isb + dsb sy + eret + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ReturnToCore ( +// IN EFI_STATUS Status, +// IN UINTN CoreSp +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ReturnToCore) + // Zero Exception Syndrome Register to prevent QEMU from random crashing. + msr esr_el1, xzr + msr spsr_el1, xzr + msr elr_el1, xzr + msr far_el1, xzr + // Switch to Core Stack. + mov sp, x1 + // Restore registers and Stack. + ldp q8, q9, [sp, #0xe0] + ldp q10, q11, [sp, #0xc0] + ldp q12, q13, [sp, #0xa0] + ldp q14, q15, [sp, #0x80] + + ldr x16, [sp, #0x78] + ldp x17, x18, [sp, #0x60] + ldp x19, x20, [sp, #0x50] + ldp x21, x22, [sp, #0x40] + ldp x23, x24, [sp, #0x30] + ldp x25, x26, [sp, #0x20] + ldp x27, x28, [sp, #0x10] + ldp x29, x30, [sp] + add sp, sp, #0x100 + // Enable interrupts. + msr daifclr, #0xf + isb + ret + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ArmSetPan ( +// VOID +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ArmSetPan) + msr pan, #1 + ret + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ArmClearPan ( +// VOID +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ArmClearPan) + msr pan, #0 + ret diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index f764309f11..21e8bf98dd 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -1,210 +1,210 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include -#include -#include -#include - -#include "DxeMain.h" - -STATIC UINTN mCoreSp; -UINTN gUartBaseAddress; - -EFI_STATUS -EFIAPI -ArmCallRing3 ( - IN RING3_CALL_DATA *Data, - IN VOID *StackPointer, - IN VOID *EntryPoint, - IN VOID *SysCallStack, - IN VOID *CoreStack - ); - -VOID -EFIAPI -ReturnToCore ( - IN EFI_STATUS Status, - IN UINTN CoreSp - ); - -VOID -EFIAPI -ArmSetPan ( - VOID - ); - -VOID -EFIAPI -ArmClearPan ( - VOID - ); - -STATIC -EFI_STATUS -EFIAPI -SysCallBootService ( - IN UINT8 Type, - IN VOID *CoreRbp, - IN VOID *UserRsp - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Physical; - - if (Type == SysCallReturnToCore) { - ReturnToCore (*(EFI_STATUS *)CoreRbp, mCoreSp); - } - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)), - &Physical - ); - if (EFI_ERROR (Status)) { - return Status; - } - - DisableSMAP (); - CopyMem ((VOID *)((UINTN)Physical + sizeof (UINTN)), (VOID *)UserRsp, 8 * sizeof (UINTN)); - - SetUefiImageMemoryAttributes ( - gUartBaseAddress, - EFI_PAGE_SIZE, - EFI_MEMORY_XP - ); - EnableSMAP (); - - Status = CallBootService ( - Type, - (CORE_STACK *)CoreRbp, - (RING3_STACK *)(UINTN)Physical - ); - - SetUefiImageMemoryAttributes ( - gUartBaseAddress, - EFI_PAGE_SIZE, - EFI_MEMORY_XP | EFI_MEMORY_USER - ); - - CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); - - return Status; -} - -VOID -EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries - ) -{ - UINTN Tcr; - UINTN Index; - EARLY_PL011_BASE_ADDRESS *UartBase; - EFI_PHYSICAL_ADDRESS Physical; - EFI_HOB_GENERIC_HEADER *Ring3Hob; - UINT16 HobLength; - EFI_STATUS Status; - // - // If HCR_EL2.NV is 1 and the current Exception level is EL1, - // then EL1 read accesses to the CurrentEL register return a value of 0x2 in bits[3:2]. - // CurrentEL == 1 -> HCR_EL2.NV == 0 - // - // If stage 1 is enabled and stage 1 Base permissions use Direct permissions, - // then GCS access is not permitted and UnprivGCS and PrivGCS are not present. - // - // Disable Hierarchical permissions just in case. - // - Tcr = ArmGetTCR (); - Tcr |= TCR_EL1_HPD0_MASK | TCR_EL1_HPD1_MASK; - ArmSetTCR (Tcr); - // - // Problem 1: Uart is memory maped. - // - for (Index = 0; Index < NumberOfEntries; ++Index) { - if (CompareGuid (&gEfiHobListGuid, &(Table[Index].VendorGuid))) { - UartBase = GET_GUID_HOB_DATA (Table[Index].VendorTable); - gUartBaseAddress = UartBase->DebugAddress; - // - // Copy Hob into Ring3. - // - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - 1, - &Physical - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Hob.\n")); - ASSERT (FALSE); - } - DEBUG ((DEBUG_ERROR, "UartBaseAddress = %p.\n", gUartBaseAddress)); - - Ring3Hob = (EFI_HOB_GENERIC_HEADER *)(UINTN)Physical; - - HobLength = (UINT16)((sizeof (EFI_HOB_GUID_TYPE) + sizeof (EARLY_PL011_BASE_ADDRESS) + 0x7) & (~0x7)); - - Ring3Hob->HobType = EFI_HOB_TYPE_GUID_EXTENSION; - Ring3Hob->HobLength = HobLength; - Ring3Hob->Reserved = 0; - - CopyGuid (&((EFI_HOB_GUID_TYPE *)Ring3Hob)->Name, &gEarlyPL011BaseAddressGuid); - - Ring3Hob = (EFI_HOB_GENERIC_HEADER *)((UINTN)Ring3Hob + HobLength); - - Ring3Hob->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; - Ring3Hob->HobLength = sizeof (EFI_HOB_GENERIC_HEADER); - Ring3Hob->Reserved = 0; - - Table[Index].VendorTable = (VOID *)(UINTN)Physical; - UartBase = GET_GUID_HOB_DATA (Table[Index].VendorTable); - UartBase->DebugAddress = gUartBaseAddress; - } - } - - if (ArmHasPan ()) { - // - // Enable Privileged Access Never feature. - // - ArmSetPan (); - } - - InitializeSysCallHandler ((VOID *)SysCallBootService); -} - -VOID -EFIAPI -DisableSMAP ( - VOID - ) -{ - if (ArmHasPan ()) { - ArmClearPan (); - } -} - -VOID -EFIAPI -EnableSMAP ( - VOID - ) -{ - if (ArmHasPan ()) { - ArmSetPan (); - } -} - -EFI_STATUS -EFIAPI -CallRing3 ( - IN RING3_CALL_DATA *Data - ) -{ - return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp); -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include +#include +#include +#include + +#include "DxeMain.h" + +STATIC UINTN mCoreSp; +UINTN gUartBaseAddress; + +EFI_STATUS +EFIAPI +ArmCallRing3 ( + IN RING3_CALL_DATA *Data, + IN VOID *StackPointer, + IN VOID *EntryPoint, + IN VOID *SysCallStack, + IN VOID *CoreStack + ); + +VOID +EFIAPI +ReturnToCore ( + IN EFI_STATUS Status, + IN UINTN CoreSp + ); + +VOID +EFIAPI +ArmSetPan ( + VOID + ); + +VOID +EFIAPI +ArmClearPan ( + VOID + ); + +STATIC +EFI_STATUS +EFIAPI +SysCallBootService ( + IN UINT8 Type, + IN VOID *CoreRbp, + IN VOID *UserRsp + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Physical; + + if (Type == SysCallReturnToCore) { + ReturnToCore (*(EFI_STATUS *)CoreRbp, mCoreSp); + } + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)), + &Physical + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DisableSMAP (); + CopyMem ((VOID *)((UINTN)Physical + sizeof (UINTN)), (VOID *)UserRsp, 8 * sizeof (UINTN)); + + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP + ); + EnableSMAP (); + + Status = CallBootService ( + Type, + (CORE_STACK *)CoreRbp, + (RING3_STACK *)(UINTN)Physical + ); + + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + + CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); + + return Status; +} + +VOID +EFIAPI +InitializeMsr ( + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries + ) +{ + UINTN Tcr; + UINTN Index; + EARLY_PL011_BASE_ADDRESS *UartBase; + EFI_PHYSICAL_ADDRESS Physical; + EFI_HOB_GENERIC_HEADER *Ring3Hob; + UINT16 HobLength; + EFI_STATUS Status; + // + // If HCR_EL2.NV is 1 and the current Exception level is EL1, + // then EL1 read accesses to the CurrentEL register return a value of 0x2 in bits[3:2]. + // CurrentEL == 1 -> HCR_EL2.NV == 0 + // + // If stage 1 is enabled and stage 1 Base permissions use Direct permissions, + // then GCS access is not permitted and UnprivGCS and PrivGCS are not present. + // + // Disable Hierarchical permissions just in case. + // + Tcr = ArmGetTCR (); + Tcr |= TCR_EL1_HPD0_MASK | TCR_EL1_HPD1_MASK; + ArmSetTCR (Tcr); + // + // Problem 1: Uart is memory maped. + // + for (Index = 0; Index < NumberOfEntries; ++Index) { + if (CompareGuid (&gEfiHobListGuid, &(Table[Index].VendorGuid))) { + UartBase = GET_GUID_HOB_DATA (Table[Index].VendorTable); + gUartBaseAddress = UartBase->DebugAddress; + // + // Copy Hob into Ring3. + // + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + 1, + &Physical + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Hob.\n")); + ASSERT (FALSE); + } + DEBUG ((DEBUG_ERROR, "UartBaseAddress = %p.\n", gUartBaseAddress)); + + Ring3Hob = (EFI_HOB_GENERIC_HEADER *)(UINTN)Physical; + + HobLength = (UINT16)((sizeof (EFI_HOB_GUID_TYPE) + sizeof (EARLY_PL011_BASE_ADDRESS) + 0x7) & (~0x7)); + + Ring3Hob->HobType = EFI_HOB_TYPE_GUID_EXTENSION; + Ring3Hob->HobLength = HobLength; + Ring3Hob->Reserved = 0; + + CopyGuid (&((EFI_HOB_GUID_TYPE *)Ring3Hob)->Name, &gEarlyPL011BaseAddressGuid); + + Ring3Hob = (EFI_HOB_GENERIC_HEADER *)((UINTN)Ring3Hob + HobLength); + + Ring3Hob->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; + Ring3Hob->HobLength = sizeof (EFI_HOB_GENERIC_HEADER); + Ring3Hob->Reserved = 0; + + Table[Index].VendorTable = (VOID *)(UINTN)Physical; + UartBase = GET_GUID_HOB_DATA (Table[Index].VendorTable); + UartBase->DebugAddress = gUartBaseAddress; + } + } + + if (ArmHasPan ()) { + // + // Enable Privileged Access Never feature. + // + ArmSetPan (); + } + + InitializeSysCallHandler ((VOID *)SysCallBootService); +} + +VOID +EFIAPI +DisableSMAP ( + VOID + ) +{ + if (ArmHasPan ()) { + ArmClearPan (); + } +} + +VOID +EFIAPI +EnableSMAP ( + VOID + ) +{ + if (ArmHasPan ()) { + ArmSetPan (); + } +} + +EFI_STATUS +EFIAPI +CallRing3 ( + IN RING3_CALL_DATA *Data + ) +{ + return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp); +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index 0804cf453f..4596465672 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -1,148 +1,148 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause -// -//------------------------------------------------------------------------------ - -#include - -.arch armv8.1a - -//------------------------------------------------------------------------------ -// EFI_STATUS -// EFIAPI -// CallInstallMultipleProtocolInterfaces ( -// IN EFI_HANDLE *Handle, -// IN VOID **ArgList, -// IN UINT32 ArgListSize, -// IN VOID *Function -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(CallInstallMultipleProtocolInterfaces) - push {R4-R8, LR} - mov R7, SP - // Save function input. - mov R4, R3 - mov R5, R1 - mov R6, R2 - // Prepare registers for call. - ldmfd R5, {R1-R3} - // Prepare stack for call. - cmp R6, #3 - ble call - - add R5, R5, R6, LSL #2 - sub R6, R6, #3 - tst R6, #1 - beq copy - // To align stack on 8 bytes. - add R5, R5, #0x4 - add R6, R6, #1 -copy: - sub R5, R5, #0x4 - ldmfd R5, {R8} - push {R8} - subs R6, R6, #1 - bne copy - -call: - blx R4 - - mov SP, R7 - pop {R4-R8, LR} - bx LR - -//------------------------------------------------------------------------------ -// EFI_STATUS -// EFIAPI -// CallRing3 ( -// IN RING3_CALL_DATA *Data -// ); -// -// (r0) Data -// (r1) gRing3CallStackTop -// (r2) gRing3EntryPoint -// (r3) gCoreSysCallStackTop -// -// (On Core Stack) &CoreSp -//------------------------------------------------------------------------------ -ASM_FUNC(ArmCallRing3) - // Save registers. - push {R4-R12, LR} - // R6 is &CoreSp - ldr R6, [SP, #0x28] - +//------------------------------------------------------------------------------ +// +// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +//------------------------------------------------------------------------------ + +#include + +.arch armv8.1a + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// CallInstallMultipleProtocolInterfaces ( +// IN EFI_HANDLE *Handle, +// IN VOID **ArgList, +// IN UINT32 ArgListSize, +// IN VOID *Function +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(CallInstallMultipleProtocolInterfaces) + push {R4-R8, LR} + mov R7, SP + // Save function input. + mov R4, R3 + mov R5, R1 + mov R6, R2 + // Prepare registers for call. + ldmfd R5, {R1-R3} + // Prepare stack for call. + cmp R6, #3 + ble call + + add R5, R5, R6, LSL #2 + sub R6, R6, #3 + tst R6, #1 + beq copy + // To align stack on 8 bytes. + add R5, R5, #0x4 + add R6, R6, #1 +copy: + sub R5, R5, #0x4 + ldmfd R5, {R8} + push {R8} + subs R6, R6, #1 + bne copy + +call: + blx R4 + + mov SP, R7 + pop {R4-R8, LR} + bx LR + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// CallRing3 ( +// IN RING3_CALL_DATA *Data +// ); +// +// (r0) Data +// (r1) gRing3CallStackTop +// (r2) gRing3EntryPoint +// (r3) gCoreSysCallStackTop +// +// (On Core Stack) &CoreSp +//------------------------------------------------------------------------------ +ASM_FUNC(ArmCallRing3) + // Save registers. + push {R4-R12, LR} + // R6 is &CoreSp + ldr R6, [SP, #0x28] + #if (FixedPcdGet32(PcdVFPEnabled)) // Save vstm registers in case they are used in optimizations. vpush {d0-d15} #endif - - // Disable interrupts. - mrs R4, CPSR - cpsid if - isb - - // Set SP_usr to gRing3CallStackTop. - push {R1} - mov R1, SP - ldmia R1, {SP}^ - pop {R1} - // Set SPSR M[3:0] bits to User mode. - and R4, R4, #0xFFFFFFF0 - - // Save Core SP and switch to CoreSysCall Stack. - mov R5, SP - str R5, [R6] - mov SP, R3 - - push {R4} - push {R2} - rfefd SP - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// ReturnToCore ( -// IN EFI_STATUS Status, -// IN UINTN CoreSp -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(ReturnToCore) - // Switch to Core Stack. - mov SP, R1 - - // Restore registers and Stack. + + // Disable interrupts. + mrs R4, CPSR + cpsid if + isb + + // Set SP_usr to gRing3CallStackTop. + push {R1} + mov R1, SP + ldmia R1, {SP}^ + pop {R1} + // Set SPSR M[3:0] bits to User mode. + and R4, R4, #0xFFFFFFF0 + + // Save Core SP and switch to CoreSysCall Stack. + mov R5, SP + str R5, [R6] + mov SP, R3 + + push {R4} + push {R2} + rfefd SP + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ReturnToCore ( +// IN EFI_STATUS Status, +// IN UINTN CoreSp +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ReturnToCore) + // Switch to Core Stack. + mov SP, R1 + + // Restore registers and Stack. #if (FixedPcdGet32(PcdVFPEnabled)) vpop {d0-d15} #endif - - pop {R4-R12, LR} - - // Enable interrupts. - cpsie if - isb - - bx LR - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// ArmSetPan ( -// VOID -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(ArmSetPan) - setpan #1 - bx LR - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// ArmClearPan ( -// VOID -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(ArmClearPan) - setpan #0 - bx LR + + pop {R4-R12, LR} + + // Enable interrupts. + cpsie if + isb + + bx LR + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ArmSetPan ( +// VOID +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ArmSetPan) + setpan #1 + bx LR + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ArmClearPan ( +// VOID +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ArmClearPan) + setpan #0 + bx LR diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c index 79ca473028..8ab94b67d7 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -1,145 +1,145 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include -#include - -#include "DxeMain.h" - -STATIC UINTN mCoreSp; - -EFI_STATUS -EFIAPI -ArmCallRing3 ( - IN RING3_CALL_DATA *Data, - IN VOID *StackPointer, - IN VOID *EntryPoint, - IN VOID *SysCallStack, - IN VOID *CoreStack - ); - -VOID -EFIAPI -ReturnToCore ( - IN EFI_STATUS Status, - IN UINTN CoreSp - ); - -VOID -EFIAPI -ArmSetPan ( - VOID - ); - -VOID -EFIAPI -ArmClearPan ( - VOID - ); - -STATIC -EFI_STATUS -EFIAPI -SysCallBootService ( - IN UINT8 Type, - IN VOID *CoreRbp, - IN VOID *UserRsp - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Physical; - - if (Type == SysCallReturnToCore) { - ReturnToCore (*(EFI_STATUS *)CoreRbp, mCoreSp); - } - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)), - &Physical - ); - if (EFI_ERROR (Status)) { - return Status; - } - - DisableSMAP (); - // - // First 3 arguments are passed through R1-R3 and copied to SysCall Stack. - // - CopyMem ((VOID *)((UINTN)Physical + 2 * sizeof (UINTN)), (VOID *)CoreRbp, 3 * sizeof (UINTN)); - // - // All remaining arguments are on User Stack. - // - CopyMem ((VOID *)((UINTN)Physical + 5 * sizeof (UINTN)), (VOID *)UserRsp, 4 * sizeof (UINTN)); - EnableSMAP (); - - Status = CallBootService ( - Type, - (CORE_STACK *)CoreRbp, - (RING3_STACK *)(UINTN)Physical - ); - - CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); - - return Status; -} - -VOID -EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries - ) -{ - // - // TODO: EFI_CONFIGURATION_TABLE, HOB_DATA, Uart are accessible to User. - // Fix PageTable initialization. - // - if (ArmHasPan ()) { - // - // Enable Privileged Access Never feature. - // - ArmSetPan (); - } - - InitializeSysCallHandler (SysCallBootService); -} - -// -// TODO: Refactoring. -// -VOID -EFIAPI -DisableSMAP ( - VOID - ) -{ - if (ArmHasPan ()) { - ArmClearPan (); - } -} - -VOID -EFIAPI -EnableSMAP ( - VOID - ) -{ - if (ArmHasPan ()) { - ArmSetPan (); - } -} - -EFI_STATUS -EFIAPI -CallRing3 ( - IN RING3_CALL_DATA *Data - ) -{ - return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp); -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include +#include + +#include "DxeMain.h" + +STATIC UINTN mCoreSp; + +EFI_STATUS +EFIAPI +ArmCallRing3 ( + IN RING3_CALL_DATA *Data, + IN VOID *StackPointer, + IN VOID *EntryPoint, + IN VOID *SysCallStack, + IN VOID *CoreStack + ); + +VOID +EFIAPI +ReturnToCore ( + IN EFI_STATUS Status, + IN UINTN CoreSp + ); + +VOID +EFIAPI +ArmSetPan ( + VOID + ); + +VOID +EFIAPI +ArmClearPan ( + VOID + ); + +STATIC +EFI_STATUS +EFIAPI +SysCallBootService ( + IN UINT8 Type, + IN VOID *CoreRbp, + IN VOID *UserRsp + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Physical; + + if (Type == SysCallReturnToCore) { + ReturnToCore (*(EFI_STATUS *)CoreRbp, mCoreSp); + } + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)), + &Physical + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DisableSMAP (); + // + // First 3 arguments are passed through R1-R3 and copied to SysCall Stack. + // + CopyMem ((VOID *)((UINTN)Physical + 2 * sizeof (UINTN)), (VOID *)CoreRbp, 3 * sizeof (UINTN)); + // + // All remaining arguments are on User Stack. + // + CopyMem ((VOID *)((UINTN)Physical + 5 * sizeof (UINTN)), (VOID *)UserRsp, 4 * sizeof (UINTN)); + EnableSMAP (); + + Status = CallBootService ( + Type, + (CORE_STACK *)CoreRbp, + (RING3_STACK *)(UINTN)Physical + ); + + CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); + + return Status; +} + +VOID +EFIAPI +InitializeMsr ( + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries + ) +{ + // + // TODO: EFI_CONFIGURATION_TABLE, HOB_DATA, Uart are accessible to User. + // Fix PageTable initialization. + // + if (ArmHasPan ()) { + // + // Enable Privileged Access Never feature. + // + ArmSetPan (); + } + + InitializeSysCallHandler (SysCallBootService); +} + +// +// TODO: Refactoring. +// +VOID +EFIAPI +DisableSMAP ( + VOID + ) +{ + if (ArmHasPan ()) { + ArmClearPan (); + } +} + +VOID +EFIAPI +EnableSMAP ( + VOID + ) +{ + if (ArmHasPan ()) { + ArmSetPan (); + } +} + +EFI_STATUS +EFIAPI +CallRing3 ( + IN RING3_CALL_DATA *Data + ) +{ + return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp); +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 9b6b82f5c7..e729c3c10f 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -1,1434 +1,1434 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include "DxeMain.h" -#include "SupportedProtocols.h" - -LIST_ENTRY mProtocolsHead = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolsHead); - -typedef struct { - VOID *Core; - VOID *Ring3; - LIST_ENTRY Link; -} INTERFACE; - -UINTN mRing3InterfacePointer = 0; - -CHAR8 *SysCallNames[] = { - // - // BootServices - // - "SysCallReturnToCore", // Must always be zero for CoreBootServices.nasm. - "SysCallLocateProtocol", - "SysCallOpenProtocol", - "SysCallInstallMultipleProtocolInterfaces", - "SysCallCloseProtocol", - "SysCallHandleProtocol", - "SysCallAllocatePages", - "SysCallFreePages", - "SysCallRaiseTpl", - "SysCallRestoreTpl", - "SysCallLocateHandleBuffer", - "SysCallCalculateCrc32", - // - // RuntimeServices - // - "SysCallGetVariable", - // - // Protocols - // - "SysCallBlockIoReset", - "SysCallBlockIoRead", - "SysCallBlockIoWrite", - "SysCallBlockIoFlush", - "SysCallDiskIoRead", - "SysCallDiskIoWrite", - "SysCallUnicodeStriColl", - "SysCallUnicodeMetaiMatch", - "SysCallUnicodeStrLwr", - "SysCallUnicodeStrUpr", - "SysCallUnicodeFatToStr", - "SysCallUnicodeStrToFat", - "SysCallMax" -}; - -EFI_STATUS -EFIAPI -CallInstallMultipleProtocolInterfaces ( - IN EFI_HANDLE *Handle, - IN VOID **ArgList, - IN UINT32 ArgListSize, - IN VOID *Function - ); - -VOID -EFIAPI -FreeProtocolsList ( - VOID - ) -{ - LIST_ENTRY *Link; - INTERFACE *Protocol; - - for (Link = mProtocolsHead.BackLink; Link != &mProtocolsHead; Link = mProtocolsHead.BackLink) { - Protocol = BASE_CR (Link, INTERFACE, Link); - RemoveEntryList (Link); - FreePool (Protocol); - } -} - -STATIC -EFI_STATUS -EFIAPI -FindGuid ( - IN EFI_GUID *Ring3, - OUT EFI_GUID **Core, - OUT UINT32 *CoreSize - ) -{ - ASSERT (Ring3 != NULL); - ASSERT (Core != NULL); - ASSERT (CoreSize != NULL); - - if (CompareGuid (Ring3, &gEfiDevicePathUtilitiesProtocolGuid)) { - - *Core = &gEfiDevicePathUtilitiesProtocolGuid; - *CoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiLoadedImageProtocolGuid)) { - - *Core = &gEfiLoadedImageProtocolGuid; - *CoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiBlockIoProtocolGuid)) { - - *Core = &gEfiBlockIoProtocolGuid; - *CoreSize = sizeof (EFI_BLOCK_IO_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiDiskIoProtocolGuid)) { - - *Core = &gEfiDiskIoProtocolGuid; - *CoreSize = sizeof (EFI_DISK_IO_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiDriverBindingProtocolGuid)) { - - *Core = &gEfiDriverBindingProtocolGuid; - *CoreSize = sizeof (EFI_DRIVER_BINDING_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiComponentNameProtocolGuid)) { - - *Core = &gEfiComponentNameProtocolGuid; - *CoreSize = sizeof (EFI_COMPONENT_NAME_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiComponentName2ProtocolGuid)) { - - *Core = &gEfiComponentName2ProtocolGuid; - *CoreSize = sizeof (EFI_COMPONENT_NAME2_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiDevicePathProtocolGuid)) { - - *Core = &gEfiDevicePathProtocolGuid; - *CoreSize = sizeof (EFI_DEVICE_PATH_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiSimpleFileSystemProtocolGuid)) { - - *Core = &gEfiSimpleFileSystemProtocolGuid; - *CoreSize = sizeof (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiUnicodeCollationProtocolGuid)) { - - *Core = &gEfiUnicodeCollationProtocolGuid; - *CoreSize = sizeof (EFI_UNICODE_COLLATION_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiGlobalVariableGuid)) { - - *Core = &gEfiGlobalVariableGuid; - - } else { - DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol - %g.\n", Ring3)); - return EFI_NOT_FOUND; - } - - return EFI_SUCCESS; -} - -STATIC -VOID * -EFIAPI -FindInterface ( - IN BOOLEAN FindRing3, - IN VOID *Interface - ) -{ - LIST_ENTRY *Link; - INTERFACE *Protocol; - - for (Link = mProtocolsHead.ForwardLink; Link != &mProtocolsHead; Link = Link->ForwardLink) { - Protocol = BASE_CR (Link, INTERFACE, Link); - - if (FindRing3) { - if (Protocol->Core == Interface) { - return Protocol->Ring3; - } - } else { - if (Protocol->Ring3 == Interface) { - return Protocol->Core; - } - } - } - - return NULL; -} - -STATIC -VOID * -EFIAPI -PrepareRing3Interface ( - IN EFI_GUID *Guid, - IN VOID *CoreInterface, - IN UINT32 CoreSize - ) -{ - EFI_STATUS Status; - UINTN Ring3Limit; - VOID *Ring3Interface; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EFI_UNICODE_COLLATION_PROTOCOL *Unicode; - INTERFACE *Protocol; - - ASSERT (Guid != NULL); - ASSERT (CoreInterface != NULL); - - if (mRing3InterfacePointer == 0) { - mRing3InterfacePointer = (UINTN)gRing3Interfaces; - } - - Ring3Interface = FindInterface (TRUE, CoreInterface); - - if (Ring3Interface != NULL) { - return Ring3Interface; - } - - Ring3Limit = (UINTN)gRing3Interfaces + EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES); - - ASSERT ((mRing3InterfacePointer + CoreSize) <= Ring3Limit); - - Ring3Interface = (VOID *)mRing3InterfacePointer; - - CopyMem ((VOID *)mRing3InterfacePointer, CoreInterface, CoreSize); - mRing3InterfacePointer += CoreSize; - - Protocol = AllocatePool (sizeof (INTERFACE)); - - Protocol->Core = CoreInterface; - Protocol->Ring3 = Ring3Interface; - - InsertTailList (&mProtocolsHead, &Protocol->Link); - - if (CompareGuid (Guid, &gEfiBlockIoProtocolGuid)) { - ASSERT ((mRing3InterfacePointer + sizeof (EFI_BLOCK_IO_MEDIA)) <= Ring3Limit); - - BlockIo = (EFI_BLOCK_IO_PROTOCOL *)Ring3Interface; - - CopyMem ((VOID *)mRing3InterfacePointer, (VOID *)BlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA)); - - BlockIo->Media = (EFI_BLOCK_IO_MEDIA *)mRing3InterfacePointer; - - mRing3InterfacePointer += sizeof (EFI_BLOCK_IO_MEDIA); - } else if (CompareGuid (Guid, &gEfiUnicodeCollationProtocolGuid)) { - - Unicode = (EFI_UNICODE_COLLATION_PROTOCOL *)Ring3Interface; - - ASSERT ((mRing3InterfacePointer + AsciiStrSize (Unicode->SupportedLanguages)) <= Ring3Limit); - - Status = AsciiStrCpyS ( - (CHAR8 *)mRing3InterfacePointer, - AsciiStrSize (Unicode->SupportedLanguages), - Unicode->SupportedLanguages - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Could not copy string!\n")); - return NULL; - } - - Unicode->SupportedLanguages = (CHAR8 *)mRing3InterfacePointer; - - mRing3InterfacePointer += AsciiStrSize (Unicode->SupportedLanguages); - } - - return Ring3Interface; -} - -// -// Stack: -// rsp - User Rsp -// rbp - User Rbp -// rcx - User Rip for SYSCALL -// r11 - User RFLAGS for SYSCALL -// r9 - Argument 3 -// r8 - Argument 2 -// rdx - Argument 1 <- CoreRbp -// -EFI_STATUS -EFIAPI -CallBootService ( - IN UINT8 Type, - IN CORE_STACK *CoreRbp, - IN RING3_STACK *UserRsp - ) -{ - EFI_STATUS Status; - EFI_STATUS StatusBS; - UINT64 Attributes; - VOID *Interface; - EFI_GUID *CoreProtocol; - UINT32 MemoryCoreSize; - UINTN Argument4; - UINTN Argument5; - UINTN Argument6; - UINT32 Index; - VOID **UserArgList; - VOID *CoreArgList[MAX_LIST]; - EFI_HANDLE CoreHandle; - UINT32 PagesNumber; - EFI_PHYSICAL_ADDRESS Ring3Pages; - - EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *CoreSimpleFileSystem; - - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EFI_DISK_IO_PROTOCOL *DiskIo; - EFI_UNICODE_COLLATION_PROTOCOL *Unicode; - - CoreProtocol = NULL; - Argument4 = 0; - Argument5 = 0; - Argument6 = 0; - Interface = NULL; - // - // Check User variables. - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserRsp, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DEBUG ((DEBUG_VERBOSE, "Type: %a\n", SysCallNames[Type])); - - switch (Type) { - case SysCallLocateProtocol: - // - // Argument 1: EFI_GUID *Protocol - // Argument 2: VOID *CoreRegistration - // Argument 3: VOID **Interface - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + sizeof (EFI_GUID) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument1, &CoreProtocol, &MemoryCoreSize); - EnableSMAP (); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = gBS->LocateProtocol ( - CoreProtocol, - (VOID *)CoreRbp->Argument2, - &Interface - ); - - DisableSMAP (); - if (Interface != NULL) { - Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); - ASSERT (Interface != NULL); - - *(VOID **)CoreRbp->Argument3 = Interface; - } - EnableSMAP (); - - return Status; - - case SysCallOpenProtocol: - // - // Argument 1: EFI_HANDLE CoreUserHandle - // Argument 2: EFI_GUID *Protocol - // Argument 3: VOID **Interface OPTIONAL - // Argument 4: EFI_HANDLE CoreImageHandle - // Argument 5: EFI_HANDLE CoreControllerHandle - // Argument 6: UINT32 Attributes - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - if ((VOID **)CoreRbp->Argument3 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - } - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); - if (EFI_ERROR (Status)) { - EnableSMAP (); - return Status; - } - - Argument4 = UserRsp->Arguments[4]; - Argument5 = UserRsp->Arguments[5]; - Argument6 = UserRsp->Arguments[6]; - EnableSMAP (); - - Status = gBS->OpenProtocol ( - (EFI_HANDLE)CoreRbp->Argument1, - CoreProtocol, - ((VOID **)CoreRbp->Argument3 != NULL) ? &Interface : NULL, - (EFI_HANDLE)Argument4, - (EFI_HANDLE)Argument5, - (UINT32)Argument6 - ); - - if ((VOID **)CoreRbp->Argument3 != NULL) { - DisableSMAP (); - if (Interface != NULL) { - Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); - } - - *(VOID **)CoreRbp->Argument3 = Interface; - EnableSMAP (); - } - - return Status; - - case SysCallInstallMultipleProtocolInterfaces: - // - // Argument 1: EFI_HANDLE *Handle - // ... - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + sizeof (EFI_HANDLE *) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (VOID **) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - CoreHandle = *(EFI_HANDLE *)CoreRbp->Argument1; - UserArgList = (VOID **)CoreRbp->Argument2; - - for (Index = 0; UserArgList[Index] != NULL; Index += 2) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArgList[Index], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserArgList[Index] + sizeof (EFI_GUID) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Status = FindGuid ((EFI_GUID *)UserArgList[Index], (EFI_GUID **)&CoreArgList[Index], &MemoryCoreSize); - if (EFI_ERROR (Status)) { - EnableSMAP (); - - while (Index > 0) { - FreePool (CoreArgList[Index - 1]); - Index -= 2; - } - - return Status; - } - - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArgList[Index + 1], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserArgList[Index + 1] + MemoryCoreSize - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - CoreArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserArgList[Index + 1]); - - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] + sizeof (VOID *) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - } - EnableSMAP (); - - ASSERT (Index < MAX_LIST); - CoreArgList[Index] = NULL; - - for (Index = 0; CoreArgList[Index] != NULL; Index += 2) { - if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiDriverBindingProtocolGuid)) { - CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)CoreArgList[Index + 1]; - - mRing3DriverBindingProtocol.Supported = CoreDriverBinding->Supported; - mRing3DriverBindingProtocol.Start = CoreDriverBinding->Start; - mRing3DriverBindingProtocol.Stop = CoreDriverBinding->Stop; - - CoreDriverBinding->Supported = CoreDriverBindingSupported; - CoreDriverBinding->Start = CoreDriverBindingStart; - CoreDriverBinding->Stop = CoreDriverBindingStop; - } else if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiSimpleFileSystemProtocolGuid)) { - CoreSimpleFileSystem = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)CoreArgList[Index + 1]; - - mRing3SimpleFileSystemProtocol.OpenVolume = CoreSimpleFileSystem->OpenVolume; - - CoreSimpleFileSystem->OpenVolume = CoreOpenVolume; - - DisableSMAP (); - mRing3SimpleFileSystemPointer = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)UserArgList[Index + 1]; - EnableSMAP (); - } - } - - Status = CallInstallMultipleProtocolInterfaces ( - &CoreHandle, - CoreArgList, - Index + 1, - (VOID *)gBS->InstallMultipleProtocolInterfaces - ); - - return Status; - - case SysCallCloseProtocol: - // - // Argument 1: EFI_HANDLE CoreUserHandle - // Argument 2: EFI_GUID *Protocol - // Argument 3: EFI_HANDLE CoreAgentHandle - // Argument 4: EFI_HANDLE CoreControllerHandle - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); - if (EFI_ERROR (Status)) { - EnableSMAP (); - return Status; - } - - Argument4 = UserRsp->Arguments[4]; - EnableSMAP (); - - Status = gBS->CloseProtocol ( - (EFI_HANDLE)CoreRbp->Argument1, - CoreProtocol, - (EFI_HANDLE)CoreRbp->Argument3, - (EFI_HANDLE)Argument4 - ); - - return Status; - - case SysCallHandleProtocol: - // - // Argument 1: EFI_HANDLE CoreUserHandle - // Argument 2: EFI_GUID *Protocol - // Argument 3: VOID **Interface - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); - EnableSMAP (); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = gBS->HandleProtocol ( - (EFI_HANDLE)CoreRbp->Argument1, - CoreProtocol, - &Interface - ); - - DisableSMAP (); - if (Interface != NULL) { - Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); - ASSERT (Interface != NULL); - - *(VOID **)CoreRbp->Argument3 = Interface; - } - EnableSMAP (); - - return Status; - - case SysCallAllocatePages: - // - // Argument 1: EFI_ALLOCATE_TYPE Type - // Argument 2: EFI_MEMORY_TYPE MemoryType - // Argument 3: UINTN NumberOfPages - // Argument 4: EFI_PHYSICAL_ADDRESS *Memory - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Status = gBS->AllocatePages ( - (EFI_ALLOCATE_TYPE)CoreRbp->Argument1, - (EFI_MEMORY_TYPE)CoreRbp->Argument2, - CoreRbp->Argument3, - (EFI_PHYSICAL_ADDRESS *)&Argument4 - ); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + sizeof (EFI_PHYSICAL_ADDRESS) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - *(EFI_PHYSICAL_ADDRESS *)UserRsp->Arguments[4] = (EFI_PHYSICAL_ADDRESS)Argument4; - EnableSMAP (); - - return Status; - - case SysCallFreePages: - // - // Argument 1: UINTN NumberOfPages - // Argument 2: EFI_PHYSICAL_ADDRESS Memory - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + CoreRbp->Argument1 * EFI_PAGE_SIZE - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - return gBS->FreePages ( - *(EFI_PHYSICAL_ADDRESS *)&CoreRbp->Argument2, - CoreRbp->Argument1 - ); - - case SysCallRaiseTpl: - // - // Argument 1: EFI_TPL NewTpl - // - return (EFI_STATUS)gBS->RaiseTPL ( - (EFI_TPL)CoreRbp->Argument1 - ); - - case SysCallRestoreTpl: - // - // Argument 1: EFI_TPL NewTpl - // - gBS->RestoreTPL ((EFI_TPL)CoreRbp->Argument1); - - return EFI_SUCCESS; - - case SysCallLocateHandleBuffer: - // - // Argument 1: EFI_LOCATE_SEARCH_TYPE SearchType - // Argument 2: EFI_GUID *Protocol OPTIONAL - // Argument 3: VOID *SearchKey OPTIONAL - // Argument 4: UINTN *NumberHandles - // Argument 5: EFI_HANDLE **Buffer - // - if ((EFI_GUID *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); - EnableSMAP (); - if (EFI_ERROR (Status)) { - return Status; - } - } - - StatusBS = gBS->LocateHandleBuffer ( - (EFI_LOCATE_SEARCH_TYPE)CoreRbp->Argument1, - CoreProtocol, - (VOID *)CoreRbp->Argument3, - &Argument4, - (EFI_HANDLE **)&Argument5 - ); - - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - if ((UINTN *)UserRsp->Arguments[4] != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - *(UINTN *)UserRsp->Arguments[4] = Argument4; - } - - if ((EFI_HANDLE **)UserRsp->Arguments[5] != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[5] + sizeof (EFI_HANDLE *) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (Argument4 * sizeof (EFI_HANDLE *)); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - PagesNumber, - &Ring3Pages - ); - if (EFI_ERROR (Status)) { - return Status; - } - - CopyMem ((VOID *)(UINTN)Ring3Pages, (VOID *)Argument5, Argument4 * sizeof (EFI_HANDLE *)); - - FreePool ((VOID *)Argument5); - - *(EFI_HANDLE **)UserRsp->Arguments[5] = (EFI_HANDLE *)(UINTN)Ring3Pages; - } - EnableSMAP (); - - return StatusBS; - - case SysCallCalculateCrc32: - // - // Argument 1: VOID *Data - // Argument 2: UINTN DataSize - // Argument 3: UINT32 *Crc32 - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + CoreRbp->Argument2 - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (UINT32 *) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument4 = (UINTN)AllocatePool (CoreRbp->Argument2); - if ((VOID *)Argument4 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - DisableSMAP (); - CopyMem ((VOID *)Argument4, (VOID *)CoreRbp->Argument1, CoreRbp->Argument2); - EnableSMAP (); - - Status = gBS->CalculateCrc32 ( - (VOID *)Argument4, - CoreRbp->Argument2, - (UINT32 *)&Argument5 - ); - - DisableSMAP (); - *(UINT32 *)CoreRbp->Argument3 = (UINT32)Argument5; - EnableSMAP (); - - return Status; - - case SysCallGetVariable: - // - // Argument 1: CHAR16 *VariableName - // Argument 2: EFI_GUID *VendorGuid - // Argument 3: UINT32 *Attributes OPTIONAL - // Argument 4: UINTN *DataSize - // Argument 5: VOID *Data OPTIONAL - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - if ((UINT32 *)CoreRbp->Argument3 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (UINT32) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - } - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + StrSize ((CHAR16 *)CoreRbp->Argument1) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument6 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument1), (CHAR16 *)CoreRbp->Argument1); - if ((VOID *)Argument6 == NULL) { - EnableSMAP (); - return EFI_OUT_OF_RESOURCES; - } - - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); - if (EFI_ERROR (Status)) { - EnableSMAP (); - FreePool ((VOID *)Argument6); - return Status; - } - - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument4 = *(UINTN *)UserRsp->Arguments[4]; - - if ((VOID *)UserRsp->Arguments[5] != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[5] + Argument4 - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument5 = (UINTN)AllocatePool (Argument4); - if ((VOID *)Argument5 == NULL) { - EnableSMAP (); - FreePool ((VOID *)Argument6); - return EFI_OUT_OF_RESOURCES; - } - } - EnableSMAP (); - - Status = gRT->GetVariable ( - (CHAR16 *)Argument6, - CoreProtocol, - (UINT32 *)&Attributes, - &Argument4, - (VOID *)Argument5 - ); - - DisableSMAP (); - if ((VOID *)UserRsp->Arguments[5] != NULL) { - CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); - } - - *(UINTN *)UserRsp->Arguments[4] = Argument4; - - if ((UINT32 *)CoreRbp->Argument3 != NULL) { - *(UINT32 *)CoreRbp->Argument3 = (UINT32)Attributes; - } - EnableSMAP (); - - FreePool ((VOID *)Argument6); - - if ((VOID *)Argument5 != NULL) { - FreePool ((VOID *)Argument5); - } - - return Status; - - case SysCallBlockIoReset: - // - // Argument 1: EFI_BLOCK_IO_PROTOCOL *This - // Argument 2: BOOLEAN ExtendedVerification - // - BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (BlockIo == NULL) { - return EFI_NOT_FOUND; - } - - return BlockIo->Reset ( - BlockIo, - (BOOLEAN)CoreRbp->Argument2 - ); - - case SysCallBlockIoRead: - // - // Argument 1: EFI_BLOCK_IO_PROTOCOL *This - // Argument 2: UINT32 MediaId - // Argument 3: UINTN BufferSize - // Argument 4: VOID *Buffer - // Argument 5: EFI_LBA Lba - // - BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (BlockIo == NULL) { - return EFI_NOT_FOUND; - } - -#if defined (MDE_CPU_ARM) - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); -#else - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); -#endif - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); -#if defined (MDE_CPU_ARM) - // - // EFI_LBA Lba is aligned on 8 bytes. - // - Attributes = *(UINT64 *)&UserRsp->Arguments[6]; -#else - Attributes = *(UINT64 *)&UserRsp->Arguments[5]; -#endif - EnableSMAP (); - - Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); - if ((VOID *)Argument5 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = BlockIo->ReadBlocks ( - BlockIo, - (UINT32)CoreRbp->Argument2, - (EFI_LBA)Attributes, - CoreRbp->Argument3, - (VOID *)Argument5 - ); - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); - EnableSMAP (); - - FreePool ((VOID *)Argument5); - - return Status; - - case SysCallBlockIoWrite: - // - // Argument 1: EFI_BLOCK_IO_PROTOCOL *This - // Argument 2: UINT32 MediaId - // Argument 3: UINTN BufferSize - // Argument 4: VOID *Buffer - // Argument 5: EFI_LBA Lba - // - BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (BlockIo == NULL) { - return EFI_NOT_FOUND; - } - -#if defined (MDE_CPU_ARM) - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); -#else - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); -#endif - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); - if ((VOID *)Argument5 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - CopyMem ((VOID *)Argument5,(VOID *)UserRsp->Arguments[4], CoreRbp->Argument3); - -#if defined (MDE_CPU_ARM) - // - // EFI_LBA Lba is aligned on 8 bytes. - // - Attributes = *(UINT64 *)&UserRsp->Arguments[6]; -#else - Attributes = *(UINT64 *)&UserRsp->Arguments[5]; -#endif - EnableSMAP (); - - Status = BlockIo->WriteBlocks ( - BlockIo, - (UINT32)CoreRbp->Argument2, - (EFI_LBA)Attributes, - CoreRbp->Argument3, - (VOID *)Argument5 - ); - - FreePool ((VOID *)Argument5); - - return Status; - - case SysCallBlockIoFlush: - // - // Argument 1: EFI_BLOCK_IO_PROTOCOL *This - // - BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (BlockIo == NULL) { - return EFI_NOT_FOUND; - } - - return BlockIo->FlushBlocks (BlockIo); - - case SysCallDiskIoRead: - // - // Argument 1: EFI_DISK_IO_PROTOCOL *This - // Argument 2: UINT32 MediaId - // Argument 3: UINTN BufferSize - // Argument 4: VOID *Buffer - // Argument 5: UINT64 Offset - // - DiskIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (DiskIo == NULL) { - return EFI_NOT_FOUND; - } - -#if defined (MDE_CPU_ARM) - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); -#else - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); -#endif - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); -#if defined (MDE_CPU_ARM) - // - // UINT64 Offset is aligned on 8 bytes. - // - Attributes = *(UINT64 *)&UserRsp->Arguments[6]; -#else - Attributes = *(UINT64 *)&UserRsp->Arguments[5]; -#endif - EnableSMAP (); - - Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); - if ((VOID *)Argument5 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = DiskIo->ReadDisk ( - DiskIo, - (UINT32)CoreRbp->Argument2, - Attributes, - CoreRbp->Argument3, - (VOID *)Argument5 - ); - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); - EnableSMAP (); - - FreePool ((VOID *)Argument5); - - return Status; - - case SysCallDiskIoWrite: - // - // Argument 1: EFI_DISK_IO_PROTOCOL *This - // Argument 2: UINT32 MediaId - // Argument 3: UINTN BufferSize - // Argument 4: VOID *Buffer - // Argument 5: UINT64 Offset - // - DiskIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (DiskIo == NULL) { - return EFI_NOT_FOUND; - } - -#if defined (MDE_CPU_ARM) - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); -#else - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); -#endif - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); - if ((VOID *)Argument5 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - CopyMem ((VOID *)Argument5, (VOID *)UserRsp->Arguments[4], CoreRbp->Argument3); - -#if defined (MDE_CPU_ARM) - // - // UINT64 Offset is aligned on 8 bytes. - // - Attributes = *(UINT64 *)&UserRsp->Arguments[6]; -#else - Attributes = *(UINT64 *)&UserRsp->Arguments[5]; -#endif - EnableSMAP (); - - Status = DiskIo->WriteDisk ( - DiskIo, - (UINT32)CoreRbp->Argument2, - Attributes, - CoreRbp->Argument3, - (VOID *)Argument5 - ); - - FreePool ((VOID *)Argument5); - - return Status; - - case SysCallUnicodeStriColl: - // - // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This - // Argument 2: CHAR16 *Str1 - // Argument 3: CHAR16 *Str2 - // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (Unicode == NULL) { - return EFI_NOT_FOUND; - } - - if ((CHAR16 *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); - EnableSMAP (); - if ((VOID *)Argument4 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - if ((CHAR16 *)CoreRbp->Argument3 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + StrSize ((CHAR16 *)CoreRbp->Argument3) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument3), (CHAR16 *)CoreRbp->Argument3); - EnableSMAP (); - if ((VOID *)Argument5 == NULL) { - if ((VOID *)Argument4 != NULL) { - FreePool ((VOID *)Argument4); - } - - return EFI_OUT_OF_RESOURCES; - } - } - - Status = (EFI_STATUS)Unicode->StriColl ( - Unicode, - (CHAR16 *)Argument4, - (CHAR16 *)Argument5 - ); - - if ((VOID *)Argument4 != NULL) { - FreePool ((VOID *)Argument4); - } - - if ((VOID *)Argument5 != NULL) { - FreePool ((VOID *)Argument5); - } - - return Status; - - case SysCallUnicodeMetaiMatch: - // - // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This - // Argument 2: CHAR16 *String - // Argument 3: CHAR16 *Pattern - // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (Unicode == NULL) { - return EFI_NOT_FOUND; - } - - if ((CHAR16 *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); - EnableSMAP (); - if ((VOID *)Argument4 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - if ((CHAR16 *)CoreRbp->Argument3 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + StrSize ((CHAR16 *)CoreRbp->Argument3) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument3), (CHAR16 *)CoreRbp->Argument3); - EnableSMAP (); - if ((VOID *)Argument5 == NULL) { - if ((VOID *)Argument4 != NULL) { - FreePool ((VOID *)Argument4); - } - - return EFI_OUT_OF_RESOURCES; - } - } - - Status = (EFI_STATUS)Unicode->MetaiMatch ( - Unicode, - (CHAR16 *)Argument4, - (CHAR16 *)Argument5 - ); - - if ((VOID *)Argument4 != NULL) { - FreePool ((VOID *)Argument4); - } - - if ((VOID *)Argument5 != NULL) { - FreePool ((VOID *)Argument5); - } - - return Status; - - case SysCallUnicodeStrLwr: - // - // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This - // Argument 2: CHAR16 *Str - // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (Unicode == NULL) { - return EFI_NOT_FOUND; - } - - if ((CHAR16 *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); - EnableSMAP (); - if ((VOID *)Argument4 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - Unicode->StrLwr ( - Unicode, - (CHAR16 *)Argument4 - ); - - if ((VOID *)Argument4 != NULL) { - DisableSMAP (); - Status = StrCpyS ((CHAR16 *)CoreRbp->Argument2, StrLen ((CHAR16 *)CoreRbp->Argument2) + 1, (CHAR16 *)Argument4); - EnableSMAP (); - - FreePool ((VOID *)Argument4); - } - - return EFI_SUCCESS; - - case SysCallUnicodeStrUpr: - // - // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This - // Argument 2: CHAR16 *Str - // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (Unicode == NULL) { - return EFI_NOT_FOUND; - } - - if ((CHAR16 *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); - EnableSMAP (); - if ((VOID *)Argument4 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - Unicode->StrUpr ( - Unicode, - (CHAR16 *)Argument4 - ); - - if ((VOID *)Argument4 != NULL) { - DisableSMAP (); - Status = StrCpyS ((CHAR16 *)CoreRbp->Argument2, StrLen ((CHAR16 *)CoreRbp->Argument2) + 1, (CHAR16 *)Argument4); - EnableSMAP (); - - FreePool ((VOID *)Argument4); - } - - return EFI_SUCCESS; - - case SysCallUnicodeFatToStr: - // - // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This - // Argument 2: UINTN FatSize - // Argument 3: CHAR8 *Fat - // Argument 4: CHAR16 *String - // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (Unicode == NULL) { - return EFI_NOT_FOUND; - } - - if ((CHAR8 *)CoreRbp->Argument3 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + CoreRbp->Argument2 - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - Argument4 = (UINTN)AllocateCopyPool (CoreRbp->Argument2, (CHAR8 *)CoreRbp->Argument3); - EnableSMAP (); - if ((VOID *)Argument4 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - if ((CHAR16 *)UserRsp->Arguments[4] != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + 2 * (CoreRbp->Argument2 + 1) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument5 = (UINTN)AllocatePool (2 * (CoreRbp->Argument2 + 1)); - if ((VOID *)Argument5 == NULL) { - if ((VOID *)Argument4 != NULL) { - FreePool ((VOID *)Argument4); - } - - return EFI_OUT_OF_RESOURCES; - } - } - EnableSMAP (); - - Unicode->FatToStr ( - Unicode, - CoreRbp->Argument2, - (CHAR8 *)Argument4, - (CHAR16 *)Argument5 - ); - - if ((VOID *)Argument4 != NULL) { - FreePool ((VOID *)Argument4); - } - - if ((VOID *)Argument5 != NULL) { - DisableSMAP (); - CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, 2 * (CoreRbp->Argument2 + 1)); - EnableSMAP (); - - FreePool ((VOID *)Argument5); - } - - return EFI_SUCCESS; - - case SysCallUnicodeStrToFat: - // - // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This - // Argument 2: CHAR16 *String - // Argument 3: UINTN FatSize - // Argument 4: CHAR8 *Fat - // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (Unicode == NULL) { - return EFI_NOT_FOUND; - } - - if ((CHAR16 *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); - EnableSMAP (); - if ((VOID *)Argument4 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - if ((CHAR8 *)UserRsp->Arguments[4] != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); - if ((VOID *)Argument5 == NULL) { - if ((VOID *)Argument4 != NULL) { - FreePool ((VOID *)Argument4); - } - - return EFI_OUT_OF_RESOURCES; - } - } - EnableSMAP (); - - Status = (EFI_STATUS)Unicode->StrToFat ( - Unicode, - (CHAR16 *)Argument4, - CoreRbp->Argument3, - (CHAR8 *)Argument5 - ); - - if ((VOID *)Argument4 != NULL) { - FreePool ((VOID *)Argument4); - } - - if ((VOID *)Argument5 != NULL) { - DisableSMAP (); - CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); - EnableSMAP (); - - FreePool ((VOID *)Argument5); - } - - return Status; - - default: - DEBUG ((DEBUG_ERROR, "Ring0: Unknown syscall type.\n")); - break; - } - - return EFI_UNSUPPORTED; -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" +#include "SupportedProtocols.h" + +LIST_ENTRY mProtocolsHead = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolsHead); + +typedef struct { + VOID *Core; + VOID *Ring3; + LIST_ENTRY Link; +} INTERFACE; + +UINTN mRing3InterfacePointer = 0; + +CHAR8 *SysCallNames[] = { + // + // BootServices + // + "SysCallReturnToCore", // Must always be zero for CoreBootServices.nasm. + "SysCallLocateProtocol", + "SysCallOpenProtocol", + "SysCallInstallMultipleProtocolInterfaces", + "SysCallCloseProtocol", + "SysCallHandleProtocol", + "SysCallAllocatePages", + "SysCallFreePages", + "SysCallRaiseTpl", + "SysCallRestoreTpl", + "SysCallLocateHandleBuffer", + "SysCallCalculateCrc32", + // + // RuntimeServices + // + "SysCallGetVariable", + // + // Protocols + // + "SysCallBlockIoReset", + "SysCallBlockIoRead", + "SysCallBlockIoWrite", + "SysCallBlockIoFlush", + "SysCallDiskIoRead", + "SysCallDiskIoWrite", + "SysCallUnicodeStriColl", + "SysCallUnicodeMetaiMatch", + "SysCallUnicodeStrLwr", + "SysCallUnicodeStrUpr", + "SysCallUnicodeFatToStr", + "SysCallUnicodeStrToFat", + "SysCallMax" +}; + +EFI_STATUS +EFIAPI +CallInstallMultipleProtocolInterfaces ( + IN EFI_HANDLE *Handle, + IN VOID **ArgList, + IN UINT32 ArgListSize, + IN VOID *Function + ); + +VOID +EFIAPI +FreeProtocolsList ( + VOID + ) +{ + LIST_ENTRY *Link; + INTERFACE *Protocol; + + for (Link = mProtocolsHead.BackLink; Link != &mProtocolsHead; Link = mProtocolsHead.BackLink) { + Protocol = BASE_CR (Link, INTERFACE, Link); + RemoveEntryList (Link); + FreePool (Protocol); + } +} + +STATIC +EFI_STATUS +EFIAPI +FindGuid ( + IN EFI_GUID *Ring3, + OUT EFI_GUID **Core, + OUT UINT32 *CoreSize + ) +{ + ASSERT (Ring3 != NULL); + ASSERT (Core != NULL); + ASSERT (CoreSize != NULL); + + if (CompareGuid (Ring3, &gEfiDevicePathUtilitiesProtocolGuid)) { + + *Core = &gEfiDevicePathUtilitiesProtocolGuid; + *CoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiLoadedImageProtocolGuid)) { + + *Core = &gEfiLoadedImageProtocolGuid; + *CoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiBlockIoProtocolGuid)) { + + *Core = &gEfiBlockIoProtocolGuid; + *CoreSize = sizeof (EFI_BLOCK_IO_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiDiskIoProtocolGuid)) { + + *Core = &gEfiDiskIoProtocolGuid; + *CoreSize = sizeof (EFI_DISK_IO_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiDriverBindingProtocolGuid)) { + + *Core = &gEfiDriverBindingProtocolGuid; + *CoreSize = sizeof (EFI_DRIVER_BINDING_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiComponentNameProtocolGuid)) { + + *Core = &gEfiComponentNameProtocolGuid; + *CoreSize = sizeof (EFI_COMPONENT_NAME_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiComponentName2ProtocolGuid)) { + + *Core = &gEfiComponentName2ProtocolGuid; + *CoreSize = sizeof (EFI_COMPONENT_NAME2_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiDevicePathProtocolGuid)) { + + *Core = &gEfiDevicePathProtocolGuid; + *CoreSize = sizeof (EFI_DEVICE_PATH_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiSimpleFileSystemProtocolGuid)) { + + *Core = &gEfiSimpleFileSystemProtocolGuid; + *CoreSize = sizeof (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiUnicodeCollationProtocolGuid)) { + + *Core = &gEfiUnicodeCollationProtocolGuid; + *CoreSize = sizeof (EFI_UNICODE_COLLATION_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiGlobalVariableGuid)) { + + *Core = &gEfiGlobalVariableGuid; + + } else { + DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol - %g.\n", Ring3)); + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +STATIC +VOID * +EFIAPI +FindInterface ( + IN BOOLEAN FindRing3, + IN VOID *Interface + ) +{ + LIST_ENTRY *Link; + INTERFACE *Protocol; + + for (Link = mProtocolsHead.ForwardLink; Link != &mProtocolsHead; Link = Link->ForwardLink) { + Protocol = BASE_CR (Link, INTERFACE, Link); + + if (FindRing3) { + if (Protocol->Core == Interface) { + return Protocol->Ring3; + } + } else { + if (Protocol->Ring3 == Interface) { + return Protocol->Core; + } + } + } + + return NULL; +} + +STATIC +VOID * +EFIAPI +PrepareRing3Interface ( + IN EFI_GUID *Guid, + IN VOID *CoreInterface, + IN UINT32 CoreSize + ) +{ + EFI_STATUS Status; + UINTN Ring3Limit; + VOID *Ring3Interface; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_UNICODE_COLLATION_PROTOCOL *Unicode; + INTERFACE *Protocol; + + ASSERT (Guid != NULL); + ASSERT (CoreInterface != NULL); + + if (mRing3InterfacePointer == 0) { + mRing3InterfacePointer = (UINTN)gRing3Interfaces; + } + + Ring3Interface = FindInterface (TRUE, CoreInterface); + + if (Ring3Interface != NULL) { + return Ring3Interface; + } + + Ring3Limit = (UINTN)gRing3Interfaces + EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES); + + ASSERT ((mRing3InterfacePointer + CoreSize) <= Ring3Limit); + + Ring3Interface = (VOID *)mRing3InterfacePointer; + + CopyMem ((VOID *)mRing3InterfacePointer, CoreInterface, CoreSize); + mRing3InterfacePointer += CoreSize; + + Protocol = AllocatePool (sizeof (INTERFACE)); + + Protocol->Core = CoreInterface; + Protocol->Ring3 = Ring3Interface; + + InsertTailList (&mProtocolsHead, &Protocol->Link); + + if (CompareGuid (Guid, &gEfiBlockIoProtocolGuid)) { + ASSERT ((mRing3InterfacePointer + sizeof (EFI_BLOCK_IO_MEDIA)) <= Ring3Limit); + + BlockIo = (EFI_BLOCK_IO_PROTOCOL *)Ring3Interface; + + CopyMem ((VOID *)mRing3InterfacePointer, (VOID *)BlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA)); + + BlockIo->Media = (EFI_BLOCK_IO_MEDIA *)mRing3InterfacePointer; + + mRing3InterfacePointer += sizeof (EFI_BLOCK_IO_MEDIA); + } else if (CompareGuid (Guid, &gEfiUnicodeCollationProtocolGuid)) { + + Unicode = (EFI_UNICODE_COLLATION_PROTOCOL *)Ring3Interface; + + ASSERT ((mRing3InterfacePointer + AsciiStrSize (Unicode->SupportedLanguages)) <= Ring3Limit); + + Status = AsciiStrCpyS ( + (CHAR8 *)mRing3InterfacePointer, + AsciiStrSize (Unicode->SupportedLanguages), + Unicode->SupportedLanguages + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Could not copy string!\n")); + return NULL; + } + + Unicode->SupportedLanguages = (CHAR8 *)mRing3InterfacePointer; + + mRing3InterfacePointer += AsciiStrSize (Unicode->SupportedLanguages); + } + + return Ring3Interface; +} + +// +// Stack: +// rsp - User Rsp +// rbp - User Rbp +// rcx - User Rip for SYSCALL +// r11 - User RFLAGS for SYSCALL +// r9 - Argument 3 +// r8 - Argument 2 +// rdx - Argument 1 <- CoreRbp +// +EFI_STATUS +EFIAPI +CallBootService ( + IN UINT8 Type, + IN CORE_STACK *CoreRbp, + IN RING3_STACK *UserRsp + ) +{ + EFI_STATUS Status; + EFI_STATUS StatusBS; + UINT64 Attributes; + VOID *Interface; + EFI_GUID *CoreProtocol; + UINT32 MemoryCoreSize; + UINTN Argument4; + UINTN Argument5; + UINTN Argument6; + UINT32 Index; + VOID **UserArgList; + VOID *CoreArgList[MAX_LIST]; + EFI_HANDLE CoreHandle; + UINT32 PagesNumber; + EFI_PHYSICAL_ADDRESS Ring3Pages; + + EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *CoreSimpleFileSystem; + + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_UNICODE_COLLATION_PROTOCOL *Unicode; + + CoreProtocol = NULL; + Argument4 = 0; + Argument5 = 0; + Argument6 = 0; + Interface = NULL; + // + // Check User variables. + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserRsp, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DEBUG ((DEBUG_VERBOSE, "Type: %a\n", SysCallNames[Type])); + + switch (Type) { + case SysCallLocateProtocol: + // + // Argument 1: EFI_GUID *Protocol + // Argument 2: VOID *CoreRegistration + // Argument 3: VOID **Interface + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument1, &CoreProtocol, &MemoryCoreSize); + EnableSMAP (); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->LocateProtocol ( + CoreProtocol, + (VOID *)CoreRbp->Argument2, + &Interface + ); + + DisableSMAP (); + if (Interface != NULL) { + Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); + ASSERT (Interface != NULL); + + *(VOID **)CoreRbp->Argument3 = Interface; + } + EnableSMAP (); + + return Status; + + case SysCallOpenProtocol: + // + // Argument 1: EFI_HANDLE CoreUserHandle + // Argument 2: EFI_GUID *Protocol + // Argument 3: VOID **Interface OPTIONAL + // Argument 4: EFI_HANDLE CoreImageHandle + // Argument 5: EFI_HANDLE CoreControllerHandle + // Argument 6: UINT32 Attributes + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + if ((VOID **)CoreRbp->Argument3 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + } + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + if (EFI_ERROR (Status)) { + EnableSMAP (); + return Status; + } + + Argument4 = UserRsp->Arguments[4]; + Argument5 = UserRsp->Arguments[5]; + Argument6 = UserRsp->Arguments[6]; + EnableSMAP (); + + Status = gBS->OpenProtocol ( + (EFI_HANDLE)CoreRbp->Argument1, + CoreProtocol, + ((VOID **)CoreRbp->Argument3 != NULL) ? &Interface : NULL, + (EFI_HANDLE)Argument4, + (EFI_HANDLE)Argument5, + (UINT32)Argument6 + ); + + if ((VOID **)CoreRbp->Argument3 != NULL) { + DisableSMAP (); + if (Interface != NULL) { + Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); + } + + *(VOID **)CoreRbp->Argument3 = Interface; + EnableSMAP (); + } + + return Status; + + case SysCallInstallMultipleProtocolInterfaces: + // + // Argument 1: EFI_HANDLE *Handle + // ... + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + sizeof (EFI_HANDLE *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (VOID **) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + CoreHandle = *(EFI_HANDLE *)CoreRbp->Argument1; + UserArgList = (VOID **)CoreRbp->Argument2; + + for (Index = 0; UserArgList[Index] != NULL; Index += 2) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArgList[Index], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserArgList[Index] + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Status = FindGuid ((EFI_GUID *)UserArgList[Index], (EFI_GUID **)&CoreArgList[Index], &MemoryCoreSize); + if (EFI_ERROR (Status)) { + EnableSMAP (); + + while (Index > 0) { + FreePool (CoreArgList[Index - 1]); + Index -= 2; + } + + return Status; + } + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArgList[Index + 1], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserArgList[Index + 1] + MemoryCoreSize - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + CoreArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserArgList[Index + 1]); + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] + sizeof (VOID *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + } + EnableSMAP (); + + ASSERT (Index < MAX_LIST); + CoreArgList[Index] = NULL; + + for (Index = 0; CoreArgList[Index] != NULL; Index += 2) { + if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiDriverBindingProtocolGuid)) { + CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)CoreArgList[Index + 1]; + + mRing3DriverBindingProtocol.Supported = CoreDriverBinding->Supported; + mRing3DriverBindingProtocol.Start = CoreDriverBinding->Start; + mRing3DriverBindingProtocol.Stop = CoreDriverBinding->Stop; + + CoreDriverBinding->Supported = CoreDriverBindingSupported; + CoreDriverBinding->Start = CoreDriverBindingStart; + CoreDriverBinding->Stop = CoreDriverBindingStop; + } else if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiSimpleFileSystemProtocolGuid)) { + CoreSimpleFileSystem = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)CoreArgList[Index + 1]; + + mRing3SimpleFileSystemProtocol.OpenVolume = CoreSimpleFileSystem->OpenVolume; + + CoreSimpleFileSystem->OpenVolume = CoreOpenVolume; + + DisableSMAP (); + mRing3SimpleFileSystemPointer = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)UserArgList[Index + 1]; + EnableSMAP (); + } + } + + Status = CallInstallMultipleProtocolInterfaces ( + &CoreHandle, + CoreArgList, + Index + 1, + (VOID *)gBS->InstallMultipleProtocolInterfaces + ); + + return Status; + + case SysCallCloseProtocol: + // + // Argument 1: EFI_HANDLE CoreUserHandle + // Argument 2: EFI_GUID *Protocol + // Argument 3: EFI_HANDLE CoreAgentHandle + // Argument 4: EFI_HANDLE CoreControllerHandle + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + if (EFI_ERROR (Status)) { + EnableSMAP (); + return Status; + } + + Argument4 = UserRsp->Arguments[4]; + EnableSMAP (); + + Status = gBS->CloseProtocol ( + (EFI_HANDLE)CoreRbp->Argument1, + CoreProtocol, + (EFI_HANDLE)CoreRbp->Argument3, + (EFI_HANDLE)Argument4 + ); + + return Status; + + case SysCallHandleProtocol: + // + // Argument 1: EFI_HANDLE CoreUserHandle + // Argument 2: EFI_GUID *Protocol + // Argument 3: VOID **Interface + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + EnableSMAP (); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->HandleProtocol ( + (EFI_HANDLE)CoreRbp->Argument1, + CoreProtocol, + &Interface + ); + + DisableSMAP (); + if (Interface != NULL) { + Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); + ASSERT (Interface != NULL); + + *(VOID **)CoreRbp->Argument3 = Interface; + } + EnableSMAP (); + + return Status; + + case SysCallAllocatePages: + // + // Argument 1: EFI_ALLOCATE_TYPE Type + // Argument 2: EFI_MEMORY_TYPE MemoryType + // Argument 3: UINTN NumberOfPages + // Argument 4: EFI_PHYSICAL_ADDRESS *Memory + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Status = gBS->AllocatePages ( + (EFI_ALLOCATE_TYPE)CoreRbp->Argument1, + (EFI_MEMORY_TYPE)CoreRbp->Argument2, + CoreRbp->Argument3, + (EFI_PHYSICAL_ADDRESS *)&Argument4 + ); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + sizeof (EFI_PHYSICAL_ADDRESS) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + *(EFI_PHYSICAL_ADDRESS *)UserRsp->Arguments[4] = (EFI_PHYSICAL_ADDRESS)Argument4; + EnableSMAP (); + + return Status; + + case SysCallFreePages: + // + // Argument 1: UINTN NumberOfPages + // Argument 2: EFI_PHYSICAL_ADDRESS Memory + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + CoreRbp->Argument1 * EFI_PAGE_SIZE - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + return gBS->FreePages ( + *(EFI_PHYSICAL_ADDRESS *)&CoreRbp->Argument2, + CoreRbp->Argument1 + ); + + case SysCallRaiseTpl: + // + // Argument 1: EFI_TPL NewTpl + // + return (EFI_STATUS)gBS->RaiseTPL ( + (EFI_TPL)CoreRbp->Argument1 + ); + + case SysCallRestoreTpl: + // + // Argument 1: EFI_TPL NewTpl + // + gBS->RestoreTPL ((EFI_TPL)CoreRbp->Argument1); + + return EFI_SUCCESS; + + case SysCallLocateHandleBuffer: + // + // Argument 1: EFI_LOCATE_SEARCH_TYPE SearchType + // Argument 2: EFI_GUID *Protocol OPTIONAL + // Argument 3: VOID *SearchKey OPTIONAL + // Argument 4: UINTN *NumberHandles + // Argument 5: EFI_HANDLE **Buffer + // + if ((EFI_GUID *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + EnableSMAP (); + if (EFI_ERROR (Status)) { + return Status; + } + } + + StatusBS = gBS->LocateHandleBuffer ( + (EFI_LOCATE_SEARCH_TYPE)CoreRbp->Argument1, + CoreProtocol, + (VOID *)CoreRbp->Argument3, + &Argument4, + (EFI_HANDLE **)&Argument5 + ); + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + if ((UINTN *)UserRsp->Arguments[4] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + *(UINTN *)UserRsp->Arguments[4] = Argument4; + } + + if ((EFI_HANDLE **)UserRsp->Arguments[5] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[5] + sizeof (EFI_HANDLE *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (Argument4 * sizeof (EFI_HANDLE *)); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + &Ring3Pages + ); + if (EFI_ERROR (Status)) { + return Status; + } + + CopyMem ((VOID *)(UINTN)Ring3Pages, (VOID *)Argument5, Argument4 * sizeof (EFI_HANDLE *)); + + FreePool ((VOID *)Argument5); + + *(EFI_HANDLE **)UserRsp->Arguments[5] = (EFI_HANDLE *)(UINTN)Ring3Pages; + } + EnableSMAP (); + + return StatusBS; + + case SysCallCalculateCrc32: + // + // Argument 1: VOID *Data + // Argument 2: UINTN DataSize + // Argument 3: UINT32 *Crc32 + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + CoreRbp->Argument2 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (UINT32 *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocatePool (CoreRbp->Argument2); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + DisableSMAP (); + CopyMem ((VOID *)Argument4, (VOID *)CoreRbp->Argument1, CoreRbp->Argument2); + EnableSMAP (); + + Status = gBS->CalculateCrc32 ( + (VOID *)Argument4, + CoreRbp->Argument2, + (UINT32 *)&Argument5 + ); + + DisableSMAP (); + *(UINT32 *)CoreRbp->Argument3 = (UINT32)Argument5; + EnableSMAP (); + + return Status; + + case SysCallGetVariable: + // + // Argument 1: CHAR16 *VariableName + // Argument 2: EFI_GUID *VendorGuid + // Argument 3: UINT32 *Attributes OPTIONAL + // Argument 4: UINTN *DataSize + // Argument 5: VOID *Data OPTIONAL + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + if ((UINT32 *)CoreRbp->Argument3 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (UINT32) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + } + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + StrSize ((CHAR16 *)CoreRbp->Argument1) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument6 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument1), (CHAR16 *)CoreRbp->Argument1); + if ((VOID *)Argument6 == NULL) { + EnableSMAP (); + return EFI_OUT_OF_RESOURCES; + } + + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + if (EFI_ERROR (Status)) { + EnableSMAP (); + FreePool ((VOID *)Argument6); + return Status; + } + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = *(UINTN *)UserRsp->Arguments[4]; + + if ((VOID *)UserRsp->Arguments[5] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[5] + Argument4 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocatePool (Argument4); + if ((VOID *)Argument5 == NULL) { + EnableSMAP (); + FreePool ((VOID *)Argument6); + return EFI_OUT_OF_RESOURCES; + } + } + EnableSMAP (); + + Status = gRT->GetVariable ( + (CHAR16 *)Argument6, + CoreProtocol, + (UINT32 *)&Attributes, + &Argument4, + (VOID *)Argument5 + ); + + DisableSMAP (); + if ((VOID *)UserRsp->Arguments[5] != NULL) { + CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); + } + + *(UINTN *)UserRsp->Arguments[4] = Argument4; + + if ((UINT32 *)CoreRbp->Argument3 != NULL) { + *(UINT32 *)CoreRbp->Argument3 = (UINT32)Attributes; + } + EnableSMAP (); + + FreePool ((VOID *)Argument6); + + if ((VOID *)Argument5 != NULL) { + FreePool ((VOID *)Argument5); + } + + return Status; + + case SysCallBlockIoReset: + // + // Argument 1: EFI_BLOCK_IO_PROTOCOL *This + // Argument 2: BOOLEAN ExtendedVerification + // + BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (BlockIo == NULL) { + return EFI_NOT_FOUND; + } + + return BlockIo->Reset ( + BlockIo, + (BOOLEAN)CoreRbp->Argument2 + ); + + case SysCallBlockIoRead: + // + // Argument 1: EFI_BLOCK_IO_PROTOCOL *This + // Argument 2: UINT32 MediaId + // Argument 3: UINTN BufferSize + // Argument 4: VOID *Buffer + // Argument 5: EFI_LBA Lba + // + BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (BlockIo == NULL) { + return EFI_NOT_FOUND; + } + +#if defined (MDE_CPU_ARM) + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); +#else + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); +#endif + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); +#if defined (MDE_CPU_ARM) + // + // EFI_LBA Lba is aligned on 8 bytes. + // + Attributes = *(UINT64 *)&UserRsp->Arguments[6]; +#else + Attributes = *(UINT64 *)&UserRsp->Arguments[5]; +#endif + EnableSMAP (); + + Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); + if ((VOID *)Argument5 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = BlockIo->ReadBlocks ( + BlockIo, + (UINT32)CoreRbp->Argument2, + (EFI_LBA)Attributes, + CoreRbp->Argument3, + (VOID *)Argument5 + ); + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + + return Status; + + case SysCallBlockIoWrite: + // + // Argument 1: EFI_BLOCK_IO_PROTOCOL *This + // Argument 2: UINT32 MediaId + // Argument 3: UINTN BufferSize + // Argument 4: VOID *Buffer + // Argument 5: EFI_LBA Lba + // + BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (BlockIo == NULL) { + return EFI_NOT_FOUND; + } + +#if defined (MDE_CPU_ARM) + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); +#else + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); +#endif + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); + if ((VOID *)Argument5 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + CopyMem ((VOID *)Argument5,(VOID *)UserRsp->Arguments[4], CoreRbp->Argument3); + +#if defined (MDE_CPU_ARM) + // + // EFI_LBA Lba is aligned on 8 bytes. + // + Attributes = *(UINT64 *)&UserRsp->Arguments[6]; +#else + Attributes = *(UINT64 *)&UserRsp->Arguments[5]; +#endif + EnableSMAP (); + + Status = BlockIo->WriteBlocks ( + BlockIo, + (UINT32)CoreRbp->Argument2, + (EFI_LBA)Attributes, + CoreRbp->Argument3, + (VOID *)Argument5 + ); + + FreePool ((VOID *)Argument5); + + return Status; + + case SysCallBlockIoFlush: + // + // Argument 1: EFI_BLOCK_IO_PROTOCOL *This + // + BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (BlockIo == NULL) { + return EFI_NOT_FOUND; + } + + return BlockIo->FlushBlocks (BlockIo); + + case SysCallDiskIoRead: + // + // Argument 1: EFI_DISK_IO_PROTOCOL *This + // Argument 2: UINT32 MediaId + // Argument 3: UINTN BufferSize + // Argument 4: VOID *Buffer + // Argument 5: UINT64 Offset + // + DiskIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (DiskIo == NULL) { + return EFI_NOT_FOUND; + } + +#if defined (MDE_CPU_ARM) + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); +#else + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); +#endif + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); +#if defined (MDE_CPU_ARM) + // + // UINT64 Offset is aligned on 8 bytes. + // + Attributes = *(UINT64 *)&UserRsp->Arguments[6]; +#else + Attributes = *(UINT64 *)&UserRsp->Arguments[5]; +#endif + EnableSMAP (); + + Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); + if ((VOID *)Argument5 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = DiskIo->ReadDisk ( + DiskIo, + (UINT32)CoreRbp->Argument2, + Attributes, + CoreRbp->Argument3, + (VOID *)Argument5 + ); + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + + return Status; + + case SysCallDiskIoWrite: + // + // Argument 1: EFI_DISK_IO_PROTOCOL *This + // Argument 2: UINT32 MediaId + // Argument 3: UINTN BufferSize + // Argument 4: VOID *Buffer + // Argument 5: UINT64 Offset + // + DiskIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (DiskIo == NULL) { + return EFI_NOT_FOUND; + } + +#if defined (MDE_CPU_ARM) + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); +#else + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); +#endif + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); + if ((VOID *)Argument5 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + CopyMem ((VOID *)Argument5, (VOID *)UserRsp->Arguments[4], CoreRbp->Argument3); + +#if defined (MDE_CPU_ARM) + // + // UINT64 Offset is aligned on 8 bytes. + // + Attributes = *(UINT64 *)&UserRsp->Arguments[6]; +#else + Attributes = *(UINT64 *)&UserRsp->Arguments[5]; +#endif + EnableSMAP (); + + Status = DiskIo->WriteDisk ( + DiskIo, + (UINT32)CoreRbp->Argument2, + Attributes, + CoreRbp->Argument3, + (VOID *)Argument5 + ); + + FreePool ((VOID *)Argument5); + + return Status; + + case SysCallUnicodeStriColl: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: CHAR16 *Str1 + // Argument 3: CHAR16 *Str2 + // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + if ((CHAR16 *)CoreRbp->Argument3 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + StrSize ((CHAR16 *)CoreRbp->Argument3) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument3), (CHAR16 *)CoreRbp->Argument3); + EnableSMAP (); + if ((VOID *)Argument5 == NULL) { + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + return EFI_OUT_OF_RESOURCES; + } + } + + Status = (EFI_STATUS)Unicode->StriColl ( + Unicode, + (CHAR16 *)Argument4, + (CHAR16 *)Argument5 + ); + + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + if ((VOID *)Argument5 != NULL) { + FreePool ((VOID *)Argument5); + } + + return Status; + + case SysCallUnicodeMetaiMatch: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: CHAR16 *String + // Argument 3: CHAR16 *Pattern + // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + if ((CHAR16 *)CoreRbp->Argument3 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + StrSize ((CHAR16 *)CoreRbp->Argument3) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument3), (CHAR16 *)CoreRbp->Argument3); + EnableSMAP (); + if ((VOID *)Argument5 == NULL) { + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + return EFI_OUT_OF_RESOURCES; + } + } + + Status = (EFI_STATUS)Unicode->MetaiMatch ( + Unicode, + (CHAR16 *)Argument4, + (CHAR16 *)Argument5 + ); + + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + if ((VOID *)Argument5 != NULL) { + FreePool ((VOID *)Argument5); + } + + return Status; + + case SysCallUnicodeStrLwr: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: CHAR16 *Str + // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + Unicode->StrLwr ( + Unicode, + (CHAR16 *)Argument4 + ); + + if ((VOID *)Argument4 != NULL) { + DisableSMAP (); + Status = StrCpyS ((CHAR16 *)CoreRbp->Argument2, StrLen ((CHAR16 *)CoreRbp->Argument2) + 1, (CHAR16 *)Argument4); + EnableSMAP (); + + FreePool ((VOID *)Argument4); + } + + return EFI_SUCCESS; + + case SysCallUnicodeStrUpr: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: CHAR16 *Str + // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + Unicode->StrUpr ( + Unicode, + (CHAR16 *)Argument4 + ); + + if ((VOID *)Argument4 != NULL) { + DisableSMAP (); + Status = StrCpyS ((CHAR16 *)CoreRbp->Argument2, StrLen ((CHAR16 *)CoreRbp->Argument2) + 1, (CHAR16 *)Argument4); + EnableSMAP (); + + FreePool ((VOID *)Argument4); + } + + return EFI_SUCCESS; + + case SysCallUnicodeFatToStr: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: UINTN FatSize + // Argument 3: CHAR8 *Fat + // Argument 4: CHAR16 *String + // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + + if ((CHAR8 *)CoreRbp->Argument3 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + CoreRbp->Argument2 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + Argument4 = (UINTN)AllocateCopyPool (CoreRbp->Argument2, (CHAR8 *)CoreRbp->Argument3); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + if ((CHAR16 *)UserRsp->Arguments[4] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + 2 * (CoreRbp->Argument2 + 1) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocatePool (2 * (CoreRbp->Argument2 + 1)); + if ((VOID *)Argument5 == NULL) { + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + return EFI_OUT_OF_RESOURCES; + } + } + EnableSMAP (); + + Unicode->FatToStr ( + Unicode, + CoreRbp->Argument2, + (CHAR8 *)Argument4, + (CHAR16 *)Argument5 + ); + + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + if ((VOID *)Argument5 != NULL) { + DisableSMAP (); + CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, 2 * (CoreRbp->Argument2 + 1)); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + } + + return EFI_SUCCESS; + + case SysCallUnicodeStrToFat: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: CHAR16 *String + // Argument 3: UINTN FatSize + // Argument 4: CHAR8 *Fat + // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + if ((CHAR8 *)UserRsp->Arguments[4] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); + if ((VOID *)Argument5 == NULL) { + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + return EFI_OUT_OF_RESOURCES; + } + } + EnableSMAP (); + + Status = (EFI_STATUS)Unicode->StrToFat ( + Unicode, + (CHAR16 *)Argument4, + CoreRbp->Argument3, + (CHAR8 *)Argument5 + ); + + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + if ((VOID *)Argument5 != NULL) { + DisableSMAP (); + CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + } + + return Status; + + default: + DEBUG ((DEBUG_ERROR, "Ring0: Unknown syscall type.\n")); + break; + } + + return EFI_UNSUPPORTED; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index 32a8dad0dd..ade43fc05d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -1,223 +1,223 @@ -;------------------------------------------------------------------------------ -; -; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -; SPDX-License-Identifier: BSD-3-Clause -; -;------------------------------------------------------------------------------ - -#include - -extern ASM_PFX(CallBootService) -extern ASM_PFX(gCoreSysCallStackTop) -extern ASM_PFX(gRing3CallStackTop) -extern ASM_PFX(gRing3EntryPoint) - -extern ASM_PFX(AsmReadMsr64) - -DEFAULT REL -SECTION .text - -;------------------------------------------------------------------------------ -; VOID -; EFIAPI -; DisableSMAP ( -; VOID -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(DisableSMAP) -ASM_PFX(DisableSMAP): - pushfd - pop eax - or eax, 0x40000 ; Set AC (bit 18) - push eax - popfd - ret - -;------------------------------------------------------------------------------ -; VOID -; EFIAPI -; EnableSMAP ( -; VOID -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(EnableSMAP) -ASM_PFX(EnableSMAP): - pushfd - pop eax - and eax, ~0x40000 ; Clear AC (bit 18) - push eax - popfd - ret - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; CallInstallMultipleProtocolInterfaces ( -; IN EFI_HANDLE *Handle, -; IN VOID **ArgList, -; IN UINT32 ArgListSize, -; IN VOID *Function -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(CallInstallMultipleProtocolInterfaces) -ASM_PFX(CallInstallMultipleProtocolInterfaces): - push ebp - mov ebp, esp - - ; Prepare stack for call. - mov eax, [ebp + 3 * 4] ; eax = ArgList - mov ecx, [ebp + 4 * 4] ; ecx = ArgListSize - lea eax, [eax + ecx * 4] -copy: - sub eax, 4 - push dword [eax] - sub ecx, 1 - jnz copy - push dword [ebp + 2 * 4] - - call [ebp + 5 * 4] - - ; Step over Function arguments. - mov esp, ebp - pop ebp - - ret - -%macro SetRing3DataSegmentSelectors 0 - push dword MSR_IA32_SYSENTER_CS - call ASM_PFX(AsmReadMsr64) - ; eax = RING0_CODE32_SEL - add eax, 24 ; GDT: RING0_CODE32, RING0_DATA32, RING3_CODE32, RING3_DATA32 - or eax, 3 ; RPL = 3 - - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - pop eax -%endmacro - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; CoreBootServices ( -; IN UINT8 Type, -; ... -; ); -; -; (eax) User return address. -; (ecx) Type. -; (edx) User Stack Pointer. -; -; (On User Stack) Argument 1, 2, ... -;------------------------------------------------------------------------------ -global ASM_PFX(CoreBootServices) -ASM_PFX(CoreBootServices): - ; Save User return address and Stack pointers. - push edx - push ebp - push eax - - ; Switch from User to Core data segment selectors. - mov ax, ss - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - ; Special case for SysCallReturnToCore. - cmp ecx, 0 - je coreReturnAddress - - ; Prepare CallBootService arguments. - call ASM_PFX(DisableSMAP) - mov eax, [edx + 4 * 4] ; User Argument 3 - push eax - mov eax, [edx + 3 * 4] ; User Argument 2 - push eax - mov eax, [edx + 2 * 4] ; User Argument 1 - push eax - call ASM_PFX(EnableSMAP) - mov ebp, esp - push edx - push ebp - push ecx - - sti - call ASM_PFX(CallBootService) - push eax - cli - - SetRing3DataSegmentSelectors - - pop eax - - ; Step over User Arguments [1..3] and CallBootService input. - add esp, 4*6 - - ; Prepare SYSEXIT arguments. - pop edx ; User return address. - pop ebp - pop ecx ; User Stack Pointer. - - sti - sysexit - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; CallRing3 ( -; IN RING3_CALL_DATA *Data -; ); -; -; (On User Stack) Data -;------------------------------------------------------------------------------ -global ASM_PFX(CallRing3) -ASM_PFX(CallRing3): - cli - ; Save nonvolatile registers EBX, EBP, EDI, ESI, ESP. - push ebx - push ebp - push edi - push esi - - ; Save Core Stack pointer. - mov [ASM_PFX(CoreEsp)], esp - - push dword [ASM_PFX(gRing3EntryPoint)] - push dword [ASM_PFX(gRing3CallStackTop)] - - SetRing3DataSegmentSelectors - - ; Prepare SYSEXIT arguments. - pop ecx - pop edx - mov eax, [esp + 4 * 5] ; Data - - ; Switch to User Stack. - mov ebp, ecx - - ; Pass control to user image - sti - sysexit - -coreReturnAddress: - mov esp, [ASM_PFX(CoreEsp)] - pop esi - pop edi - pop ebp - pop ebx - - call ASM_PFX(DisableSMAP) - mov eax, [edx + 2 * 4] ; User Argument 1 - push eax - call ASM_PFX(EnableSMAP) - pop eax - - sti - ret - -SECTION .data -ASM_PFX(CoreEsp): - resd 1 +;------------------------------------------------------------------------------ +; +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause +; +;------------------------------------------------------------------------------ + +#include + +extern ASM_PFX(CallBootService) +extern ASM_PFX(gCoreSysCallStackTop) +extern ASM_PFX(gRing3CallStackTop) +extern ASM_PFX(gRing3EntryPoint) + +extern ASM_PFX(AsmReadMsr64) + +DEFAULT REL +SECTION .text + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; DisableSMAP ( +; VOID +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(DisableSMAP) +ASM_PFX(DisableSMAP): + pushfd + pop eax + or eax, 0x40000 ; Set AC (bit 18) + push eax + popfd + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; EnableSMAP ( +; VOID +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(EnableSMAP) +ASM_PFX(EnableSMAP): + pushfd + pop eax + and eax, ~0x40000 ; Clear AC (bit 18) + push eax + popfd + ret + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CallInstallMultipleProtocolInterfaces ( +; IN EFI_HANDLE *Handle, +; IN VOID **ArgList, +; IN UINT32 ArgListSize, +; IN VOID *Function +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(CallInstallMultipleProtocolInterfaces) +ASM_PFX(CallInstallMultipleProtocolInterfaces): + push ebp + mov ebp, esp + + ; Prepare stack for call. + mov eax, [ebp + 3 * 4] ; eax = ArgList + mov ecx, [ebp + 4 * 4] ; ecx = ArgListSize + lea eax, [eax + ecx * 4] +copy: + sub eax, 4 + push dword [eax] + sub ecx, 1 + jnz copy + push dword [ebp + 2 * 4] + + call [ebp + 5 * 4] + + ; Step over Function arguments. + mov esp, ebp + pop ebp + + ret + +%macro SetRing3DataSegmentSelectors 0 + push dword MSR_IA32_SYSENTER_CS + call ASM_PFX(AsmReadMsr64) + ; eax = RING0_CODE32_SEL + add eax, 24 ; GDT: RING0_CODE32, RING0_DATA32, RING3_CODE32, RING3_DATA32 + or eax, 3 ; RPL = 3 + + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + pop eax +%endmacro + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CoreBootServices ( +; IN UINT8 Type, +; ... +; ); +; +; (eax) User return address. +; (ecx) Type. +; (edx) User Stack Pointer. +; +; (On User Stack) Argument 1, 2, ... +;------------------------------------------------------------------------------ +global ASM_PFX(CoreBootServices) +ASM_PFX(CoreBootServices): + ; Save User return address and Stack pointers. + push edx + push ebp + push eax + + ; Switch from User to Core data segment selectors. + mov ax, ss + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + ; Special case for SysCallReturnToCore. + cmp ecx, 0 + je coreReturnAddress + + ; Prepare CallBootService arguments. + call ASM_PFX(DisableSMAP) + mov eax, [edx + 4 * 4] ; User Argument 3 + push eax + mov eax, [edx + 3 * 4] ; User Argument 2 + push eax + mov eax, [edx + 2 * 4] ; User Argument 1 + push eax + call ASM_PFX(EnableSMAP) + mov ebp, esp + push edx + push ebp + push ecx + + sti + call ASM_PFX(CallBootService) + push eax + cli + + SetRing3DataSegmentSelectors + + pop eax + + ; Step over User Arguments [1..3] and CallBootService input. + add esp, 4*6 + + ; Prepare SYSEXIT arguments. + pop edx ; User return address. + pop ebp + pop ecx ; User Stack Pointer. + + sti + sysexit + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CallRing3 ( +; IN RING3_CALL_DATA *Data +; ); +; +; (On User Stack) Data +;------------------------------------------------------------------------------ +global ASM_PFX(CallRing3) +ASM_PFX(CallRing3): + cli + ; Save nonvolatile registers EBX, EBP, EDI, ESI, ESP. + push ebx + push ebp + push edi + push esi + + ; Save Core Stack pointer. + mov [ASM_PFX(CoreEsp)], esp + + push dword [ASM_PFX(gRing3EntryPoint)] + push dword [ASM_PFX(gRing3CallStackTop)] + + SetRing3DataSegmentSelectors + + ; Prepare SYSEXIT arguments. + pop ecx + pop edx + mov eax, [esp + 4 * 5] ; Data + + ; Switch to User Stack. + mov ebp, ecx + + ; Pass control to user image + sti + sysexit + +coreReturnAddress: + mov esp, [ASM_PFX(CoreEsp)] + pop esi + pop edi + pop ebp + pop ebx + + call ASM_PFX(DisableSMAP) + mov eax, [edx + 2 * 4] ; User Argument 1 + push eax + call ASM_PFX(EnableSMAP) + pop eax + + sti + ret + +SECTION .data +ASM_PFX(CoreEsp): + resd 1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c index aabfb9e5c4..23bd212ffe 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c @@ -1,64 +1,64 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include "DxeMain.h" - -#include - -VOID -EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries - ) -{ - UINT64 Msr; - IA32_CR4 Cr4; - IA32_EFLAGS32 Eflags; - UINT32 Ebx; - UINT32 Edx; - - Ebx = 0; - Edx = 0; - - // - // Forbid supervisor-mode accesses to any user-mode pages. - // - AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); - if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) { - Cr4.UintN = AsmReadCr4 (); - Cr4.Bits.SMAP = 1; - Cr4.Bits.SMEP = 1; - AsmWriteCr4 (Cr4.UintN); - - Eflags.UintN = AsmReadEflags (); - Eflags.Bits.AC = 0; - AsmWriteEflags (Eflags.UintN); - } - - // - // SYSENTER and SYSEXIT must be supported. - // - AsmCpuidEx (0x01, 0x0, NULL, NULL, NULL, &Edx); - if ((Edx & BIT11) == 0) { - DEBUG ((DEBUG_ERROR, "Core: SYSENTER and SYSEXIT are not supported.\n")); - CpuDeadLoop (); - } - - // - // Initialize MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_EIP and - // MSR_IA32_SYSENTER_ESP for SYSENTER and SYSEXIT. - // - Msr = RING0_CODE32_SEL; - AsmWriteMsr64 (MSR_IA32_SYSENTER_CS, Msr); - - Msr = (UINT64)(UINTN)CoreBootServices; - AsmWriteMsr64 (MSR_IA32_SYSENTER_EIP, Msr); - - Msr = (UINT64)(UINTN)gCoreSysCallStackTop; - AsmWriteMsr64 (MSR_IA32_SYSENTER_ESP, Msr); -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" + +#include + +VOID +EFIAPI +InitializeMsr ( + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries + ) +{ + UINT64 Msr; + IA32_CR4 Cr4; + IA32_EFLAGS32 Eflags; + UINT32 Ebx; + UINT32 Edx; + + Ebx = 0; + Edx = 0; + + // + // Forbid supervisor-mode accesses to any user-mode pages. + // + AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); + if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) { + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.SMAP = 1; + Cr4.Bits.SMEP = 1; + AsmWriteCr4 (Cr4.UintN); + + Eflags.UintN = AsmReadEflags (); + Eflags.Bits.AC = 0; + AsmWriteEflags (Eflags.UintN); + } + + // + // SYSENTER and SYSEXIT must be supported. + // + AsmCpuidEx (0x01, 0x0, NULL, NULL, NULL, &Edx); + if ((Edx & BIT11) == 0) { + DEBUG ((DEBUG_ERROR, "Core: SYSENTER and SYSEXIT are not supported.\n")); + CpuDeadLoop (); + } + + // + // Initialize MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_EIP and + // MSR_IA32_SYSENTER_ESP for SYSENTER and SYSEXIT. + // + Msr = RING0_CODE32_SEL; + AsmWriteMsr64 (MSR_IA32_SYSENTER_CS, Msr); + + Msr = (UINT64)(UINTN)CoreBootServices; + AsmWriteMsr64 (MSR_IA32_SYSENTER_EIP, Msr); + + Msr = (UINT64)(UINTN)gCoreSysCallStackTop; + AsmWriteMsr64 (MSR_IA32_SYSENTER_ESP, Msr); +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index facc9d543d..3a0af40149 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -1,151 +1,151 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include "DxeMain.h" - -VOID *gCoreSysCallStackTop; -VOID *gCoreSysCallStackBase; -VOID *gRing3CallStackTop; -VOID *gRing3CallStackBase; -VOID *gRing3EntryPoint; -RING3_DATA *gRing3Data; -VOID *gRing3Interfaces; - -VOID -EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries - ); - -EFI_STATUS -EFIAPI -InitializeRing3 ( - IN EFI_HANDLE ImageHandle, - IN LOADED_IMAGE_PRIVATE_DATA *Image - ) -{ - EFI_STATUS Status; - VOID *TopOfStack; - UINTN SizeOfStack; - EFI_PHYSICAL_ADDRESS Physical; - UINTN Index; - EFI_CONFIGURATION_TABLE *Conf; - - // - // Set Ring3 EntryPoint and BootServices. - // - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)), - &Physical - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Data.\n")); - return Status; - } - - gRing3Data = (RING3_DATA *)(UINTN)Physical; - - CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE)); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (gRing3Data->SystemTable.NumberOfTableEntries * sizeof (EFI_CONFIGURATION_TABLE)), - &Physical - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n")); - return Status; - } - - Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; - - for (Index = 0; Index < gRing3Data->SystemTable.NumberOfTableEntries; ++Index) { - Conf->VendorGuid = gRing3Data->SystemTable.ConfigurationTable[Index].VendorGuid; - Conf->VendorTable = gRing3Data->SystemTable.ConfigurationTable[Index].VendorTable; - ++Conf; - } - - gRing3Data->SystemTable.ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; - - // - // Initialize DxeRing3 with Supervisor privileges. - // - ChangeUefiImageRing (&Image->Info, Image->LoadedImageDevicePath, FALSE); - - Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)gRing3Data); - - ChangeUefiImageRing (&Image->Info, Image->LoadedImageDevicePath, TRUE); - - gRing3EntryPoint = gRing3Data->EntryPoint; - - gRing3Data->SystemTable.BootServices = gRing3Data->BootServices; - gRing3Data->SystemTable.RuntimeServices = gRing3Data->RuntimeServices; - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - RING3_INTERFACES_PAGES, - &Physical - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Interfaces.\n")); - CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data, - EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) - ); - return Status; - } - - gRing3Interfaces = (VOID *)(UINTN)Physical; - - SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE; - - // - // Allocate 128KB for the Core SysCall Stack. - // - gCoreSysCallStackBase = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); - ASSERT (gCoreSysCallStackBase != NULL); - - // - // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. - // - TopOfStack = (VOID *)((UINTN)gCoreSysCallStackBase + SizeOfStack - CPU_STACK_ALIGNMENT); - TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - - gCoreSysCallStackTop = TopOfStack; - - SetUefiImageMemoryAttributes ((UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP); - DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); - - // - // Allocate 128KB for the User Stack. - // - gRing3CallStackBase = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); - ASSERT (gRing3CallStackBase != NULL); - - // - // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. - // - TopOfStack = (VOID *)((UINTN)gRing3CallStackBase + SizeOfStack - CPU_STACK_ALIGNMENT); - TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - - gRing3CallStackTop = TopOfStack; - - SetUefiImageMemoryAttributes ((UINTN)gRing3CallStackBase, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); - DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop)); - - InitializeMsr ( - gRing3Data->SystemTable.ConfigurationTable, - gRing3Data->SystemTable.NumberOfTableEntries - ); - - return Status; -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" + +VOID *gCoreSysCallStackTop; +VOID *gCoreSysCallStackBase; +VOID *gRing3CallStackTop; +VOID *gRing3CallStackBase; +VOID *gRing3EntryPoint; +RING3_DATA *gRing3Data; +VOID *gRing3Interfaces; + +VOID +EFIAPI +InitializeMsr ( + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries + ); + +EFI_STATUS +EFIAPI +InitializeRing3 ( + IN EFI_HANDLE ImageHandle, + IN LOADED_IMAGE_PRIVATE_DATA *Image + ) +{ + EFI_STATUS Status; + VOID *TopOfStack; + UINTN SizeOfStack; + EFI_PHYSICAL_ADDRESS Physical; + UINTN Index; + EFI_CONFIGURATION_TABLE *Conf; + + // + // Set Ring3 EntryPoint and BootServices. + // + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)), + &Physical + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Data.\n")); + return Status; + } + + gRing3Data = (RING3_DATA *)(UINTN)Physical; + + CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE)); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (gRing3Data->SystemTable.NumberOfTableEntries * sizeof (EFI_CONFIGURATION_TABLE)), + &Physical + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n")); + return Status; + } + + Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + + for (Index = 0; Index < gRing3Data->SystemTable.NumberOfTableEntries; ++Index) { + Conf->VendorGuid = gRing3Data->SystemTable.ConfigurationTable[Index].VendorGuid; + Conf->VendorTable = gRing3Data->SystemTable.ConfigurationTable[Index].VendorTable; + ++Conf; + } + + gRing3Data->SystemTable.ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + + // + // Initialize DxeRing3 with Supervisor privileges. + // + ChangeUefiImageRing (&Image->Info, Image->LoadedImageDevicePath, FALSE); + + Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)gRing3Data); + + ChangeUefiImageRing (&Image->Info, Image->LoadedImageDevicePath, TRUE); + + gRing3EntryPoint = gRing3Data->EntryPoint; + + gRing3Data->SystemTable.BootServices = gRing3Data->BootServices; + gRing3Data->SystemTable.RuntimeServices = gRing3Data->RuntimeServices; + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + RING3_INTERFACES_PAGES, + &Physical + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Interfaces.\n")); + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data, + EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) + ); + return Status; + } + + gRing3Interfaces = (VOID *)(UINTN)Physical; + + SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE; + + // + // Allocate 128KB for the Core SysCall Stack. + // + gCoreSysCallStackBase = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); + ASSERT (gCoreSysCallStackBase != NULL); + + // + // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. + // + TopOfStack = (VOID *)((UINTN)gCoreSysCallStackBase + SizeOfStack - CPU_STACK_ALIGNMENT); + TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + + gCoreSysCallStackTop = TopOfStack; + + SetUefiImageMemoryAttributes ((UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP); + DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); + + // + // Allocate 128KB for the User Stack. + // + gRing3CallStackBase = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); + ASSERT (gRing3CallStackBase != NULL); + + // + // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. + // + TopOfStack = (VOID *)((UINTN)gRing3CallStackBase + SizeOfStack - CPU_STACK_ALIGNMENT); + TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + + gRing3CallStackTop = TopOfStack; + + SetUefiImageMemoryAttributes ((UINTN)gRing3CallStackBase, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); + DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop)); + + InitializeMsr ( + gRing3Data->SystemTable.ConfigurationTable, + gRing3Data->SystemTable.NumberOfTableEntries + ); + + return Status; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 349b29b9bc..c89a431d10 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -1,809 +1,809 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include "DxeMain.h" - -EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; -EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mRing3SimpleFileSystemProtocol; -EFI_FILE_PROTOCOL mRing3FileProtocol; - -EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; - -#if defined (MDE_CPU_AARCH64) -extern UINTN gUartBaseAddress; -#endif - -typedef struct { - EFI_FILE_PROTOCOL Protocol; - EFI_FILE_PROTOCOL *Ring3File; -} RING3_EFI_FILE_PROTOCOL; - -EFI_STATUS -EFIAPI -GoToRing3 ( - IN UINT8 Number, - IN VOID *EntryPoint, - ... - ) -{ - EFI_STATUS Status; - RING3_CALL_DATA *Input; - VA_LIST Marker; - UINTN Index; - EFI_PHYSICAL_ADDRESS Ring3Pages; - UINT32 PagesNumber; - - PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (RING3_CALL_DATA) + Number * sizeof (UINTN)); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - PagesNumber, - &Ring3Pages - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Input = (RING3_CALL_DATA *)(UINTN)Ring3Pages; - - DisableSMAP (); - Input->NumberOfArguments = Number; - Input->EntryPoint = EntryPoint; - - VA_START (Marker, EntryPoint); - for (Index = 0; Index < Number; ++Index) { - Input->Arguments[Index] = VA_ARG (Marker, UINTN); - } - VA_END (Marker); - EnableSMAP (); - -#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) - if (Number == 2) { - // - // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() - // - SetUefiImageMemoryAttributes ( - FixedPcdGet32 (PcdOvmfWorkAreaBase), - FixedPcdGet32 (PcdOvmfWorkAreaSize), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); - } -#elif defined (MDE_CPU_AARCH64) - // - // Necessary fix for DEBUG printings. - // - SetUefiImageMemoryAttributes ( - gUartBaseAddress, - EFI_PAGE_SIZE, - EFI_MEMORY_XP | EFI_MEMORY_USER - ); -#endif - Status = CallRing3 (Input); - -#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) - if (Number == 2) { - SetUefiImageMemoryAttributes ( - FixedPcdGet32 (PcdOvmfWorkAreaBase), - FixedPcdGet32 (PcdOvmfWorkAreaSize), - EFI_MEMORY_XP - ); - } -#elif defined (MDE_CPU_AARCH64) - // - // Problem 2: Uart memory maped page is not allocated at the very beginnig - // and can be used for translation table later. - // - DisableSMAP (); - // - // Problem 3: QEMU ramdomly breaks GP registers' context. - // - SetUefiImageMemoryAttributes ( - gUartBaseAddress, - EFI_PAGE_SIZE, - EFI_MEMORY_XP - ); - EnableSMAP (); -#endif - - CoreFreePages (Ring3Pages, PagesNumber); - - return Status; -} - -STATIC -VOID * -EFIAPI -Ring3Copy ( - IN VOID *Core, - IN UINT32 Size - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Ring3; - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - 1, - &Ring3 - ); - if (EFI_ERROR (Status)) { - return NULL; - } - - DisableSMAP (); - CopyMem ((VOID *)(UINTN)Ring3, Core, Size); - EnableSMAP (); - - return (VOID *)(UINTN)Ring3; -} - -EFI_STATUS -EFIAPI -CoreDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL - ) -{ - EFI_STATUS Status; - - This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); - if (This == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = GoToRing3 ( - 3, - (VOID *)mRing3DriverBindingProtocol.Supported, - This, - ControllerHandle, - RemainingDevicePath - ); - - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); - - return Status; -} - -EFI_STATUS -EFIAPI -CoreDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL - ) -{ - EFI_STATUS Status; - - This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); - if (This == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = GoToRing3 ( - 3, - (VOID *)mRing3DriverBindingProtocol.Start, - This, - ControllerHandle, - RemainingDevicePath - ); - - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); - - return Status; -} - -EFI_STATUS -EFIAPI -CoreDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer OPTIONAL - ) -{ - EFI_STATUS Status; - - This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); - if (This == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = GoToRing3 ( - 4, - (VOID *)mRing3DriverBindingProtocol.Stop, - This, - ControllerHandle, - NumberOfChildren, - ChildHandleBuffer - ); - - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileClose ( - IN EFI_FILE_PROTOCOL *This - ) -{ - EFI_STATUS Status; - RING3_EFI_FILE_PROTOCOL *File; - - File = (RING3_EFI_FILE_PROTOCOL *)This; - - Status = GoToRing3 ( - 1, - (VOID *)mRing3FileProtocol.Close, - File->Ring3File - ); - - FreePool (This); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileDelete ( - IN EFI_FILE_PROTOCOL *This - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileRead ( - IN EFI_FILE_PROTOCOL *This, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - RING3_EFI_FILE_PROTOCOL *File; - UINTN *Ring3BufferSize; - VOID *Ring3Buffer; - EFI_PHYSICAL_ADDRESS Ring3Pages; - UINT32 PagesNumber; - - if ((This == NULL) || (BufferSize == NULL)) { - return EFI_INVALID_PARAMETER; - } - - File = (RING3_EFI_FILE_PROTOCOL *)This; - Ring3Buffer = NULL; - Ring3Pages = 0; - - PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - PagesNumber, - &Ring3Pages - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; - - DisableSMAP (); - *Ring3BufferSize = *BufferSize; - EnableSMAP (); - - if (Buffer != NULL) { - Ring3Buffer = (VOID *)((UINTN *)(UINTN)Ring3Pages + 1); - } - - Status = GoToRing3 ( - 3, - (VOID *)mRing3FileProtocol.Read, - File->Ring3File, - Ring3BufferSize, - Ring3Buffer - ); - - DisableSMAP (); - if ((Ring3Buffer != NULL) && (Buffer != NULL) && (*BufferSize >= *Ring3BufferSize)) { - CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); - } - - *BufferSize = *Ring3BufferSize; - EnableSMAP (); - - CoreFreePages (Ring3Pages, PagesNumber); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileWrite ( - IN EFI_FILE_PROTOCOL *This, - IN OUT UINTN *BufferSize, - IN VOID *Buffer - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileSetPosition ( - IN EFI_FILE_PROTOCOL *This, - IN UINT64 Position - ) -{ - RING3_EFI_FILE_PROTOCOL *File; - - File = (RING3_EFI_FILE_PROTOCOL *)This; - -#if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) - return GoToRing3 ( - 2, - (VOID *)mRing3FileProtocol.SetPosition, - File->Ring3File, - Position - ); -#elif defined (MDE_CPU_IA32) - // - // UINT64 Position is passed as 2 double words on stack. - // - return GoToRing3 ( - 3, - (VOID *)mRing3FileProtocol.SetPosition, - File->Ring3File, - Position - ); -#elif defined (MDE_CPU_ARM) - // - // UINT64 Position is passed as 2 words in 2 registers and is aligned on 8 bytes. - // R0 == File->Ring3File, R1 == NULL, R2 == Position_Low, R3 == Position_High. - // - return GoToRing3 ( - 4, - (VOID *)mRing3FileProtocol.SetPosition, - File->Ring3File, - Position - ); -#endif - -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileGetPosition ( - IN EFI_FILE_PROTOCOL *This, - OUT UINT64 *Position - ) -{ - EFI_STATUS Status; - RING3_EFI_FILE_PROTOCOL *File; - EFI_PHYSICAL_ADDRESS Ring3Position; - - if ((This == NULL) || (Position == NULL)) { - return EFI_INVALID_PARAMETER; - } - - File = (RING3_EFI_FILE_PROTOCOL *)This; - Ring3Position = 0; - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - 1, - &Ring3Position - ); - if (EFI_ERROR (Status)) { - return Status; - } - - DisableSMAP (); - *(UINT64 *)(UINTN)Ring3Position = *Position; - EnableSMAP (); - - Status = GoToRing3 ( - 2, - (VOID *)mRing3FileProtocol.GetPosition, - File->Ring3File, - Ring3Position - ); - - DisableSMAP (); - *Position = *(UINT64 *)(UINTN)Ring3Position; - EnableSMAP (); - - CoreFreePages (Ring3Position, 1); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileGetInfo ( - IN EFI_FILE_PROTOCOL *This, - IN EFI_GUID *InformationType, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - RING3_EFI_FILE_PROTOCOL *File; - EFI_GUID *Ring3InformationType; - UINTN *Ring3BufferSize; - VOID *Ring3Buffer; - EFI_PHYSICAL_ADDRESS Ring3Pages; - UINT32 PagesNumber; - - if ((This == NULL) || (BufferSize == NULL)) { - return EFI_INVALID_PARAMETER; - } - - File = (RING3_EFI_FILE_PROTOCOL *)This; - Ring3Buffer = NULL; - Ring3InformationType = NULL; - Ring3Pages = 0; - - PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize + sizeof (EFI_GUID)); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - PagesNumber, - &Ring3Pages - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; - - DisableSMAP (); - *Ring3BufferSize = *BufferSize; - EnableSMAP (); - - if (Buffer != NULL) { - Ring3Buffer = (VOID *)((UINTN *)(UINTN)Ring3Pages + 1); - } - - if (InformationType != NULL) { - Ring3InformationType = (EFI_GUID *)((UINTN)Ring3Pages + sizeof (UINTN *) + *BufferSize); - - DisableSMAP (); - CopyGuid (Ring3InformationType, InformationType); - EnableSMAP (); - } - - Status = GoToRing3 ( - 4, - (VOID *)mRing3FileProtocol.GetInfo, - File->Ring3File, - Ring3InformationType, - Ring3BufferSize, - Ring3Buffer - ); - - DisableSMAP (); - if ((Ring3Buffer != NULL) && (Buffer != NULL) && (*BufferSize >= *Ring3BufferSize)) { - CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); - } - - *BufferSize = *Ring3BufferSize; - EnableSMAP (); - - CoreFreePages (Ring3Pages, PagesNumber); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileSetInfo ( - IN EFI_FILE_PROTOCOL *This, - IN EFI_GUID *InformationType, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileFlush ( - IN EFI_FILE_PROTOCOL *This - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileOpenEx ( - IN EFI_FILE_PROTOCOL *This, - OUT EFI_FILE_PROTOCOL **NewHandle, - IN CHAR16 *FileName, - IN UINT64 OpenMode, - IN UINT64 Attributes, - IN OUT EFI_FILE_IO_TOKEN *Token - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileReadEx ( - IN EFI_FILE_PROTOCOL *This, - IN OUT EFI_FILE_IO_TOKEN *Token - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileWriteEx ( - IN EFI_FILE_PROTOCOL *This, - IN OUT EFI_FILE_IO_TOKEN *Token - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileFlushEx ( - IN EFI_FILE_PROTOCOL *This, - IN OUT EFI_FILE_IO_TOKEN *Token - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileOpen ( - IN EFI_FILE_PROTOCOL *This, - OUT EFI_FILE_PROTOCOL **NewHandle, - IN CHAR16 *FileName, - IN UINT64 OpenMode, - IN UINT64 Attributes - ) -{ - EFI_STATUS Status; - RING3_EFI_FILE_PROTOCOL *File; - RING3_EFI_FILE_PROTOCOL *NewFile; - EFI_FILE_PROTOCOL **Ring3NewHandle; - CHAR16 *Ring3FileName; - EFI_PHYSICAL_ADDRESS Ring3Pages; - UINT32 PagesNumber; - - if ((This == NULL) || (NewHandle == NULL) || (FileName == NULL)) { - return EFI_INVALID_PARAMETER; - } - - File = (RING3_EFI_FILE_PROTOCOL *)This; - Ring3NewHandle = NULL; - Ring3FileName = NULL; - Ring3Pages = 0; - - PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (EFI_FILE_PROTOCOL *) + StrSize (FileName)); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - PagesNumber, - &Ring3Pages - ); - if (EFI_ERROR (Status)) { - *NewHandle = NULL; - return Status; - } - - Ring3NewHandle = (EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages; - Ring3FileName = (CHAR16 *)((EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages + 1); - - DisableSMAP (); - Status = StrCpyS (Ring3FileName, StrLen (FileName) + 1, FileName); - EnableSMAP (); - if (EFI_ERROR (Status)) { - *NewHandle = NULL; - CoreFreePages (Ring3Pages, PagesNumber); - return Status; - } - -#if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) - Status = GoToRing3 ( - 5, - (VOID *)mRing3FileProtocol.Open, - File->Ring3File, - Ring3NewHandle, - Ring3FileName, - OpenMode, - Attributes - ); -#elif defined (MDE_CPU_IA32) - // - // UINT64 OpenMode and Attributes are each passed as 2 double words on stack. - // - Status = GoToRing3 ( - 7, - (VOID *)mRing3FileProtocol.Open, - File->Ring3File, - Ring3NewHandle, - Ring3FileName, - OpenMode, - Attributes - ); -#elif defined (MDE_CPU_ARM) - // - // UINT64 OpenMode and Attributes are each passed as 2 words on stack. - // Each of them is aligned on 8 bytes. - // R0 == File->Ring3File, R1 == Ring3NewHandle, R2 == Ring3FileName, R3 == NULL, - // [SP] == OpenMode, [SP + 8] == Attributes. - // - Status = GoToRing3 ( - 8, - (VOID *)mRing3FileProtocol.Open, - File->Ring3File, - Ring3NewHandle, - Ring3FileName, - OpenMode, - Attributes - ); -#endif - if (EFI_ERROR (Status)) { - *NewHandle = NULL; - CoreFreePages (Ring3Pages, PagesNumber); - return Status; - } - - NewFile = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); - if (NewFile == NULL) { - *NewHandle = NULL; - CoreFreePages (Ring3Pages, PagesNumber); - return EFI_OUT_OF_RESOURCES; - } - - NewFile->Protocol.Revision = mRing3FileProtocol.Revision; - NewFile->Protocol.Open = CoreFileOpen; - NewFile->Protocol.Close = CoreFileClose; - NewFile->Protocol.Delete = CoreFileDelete; - NewFile->Protocol.Read = CoreFileRead; - NewFile->Protocol.Write = CoreFileWrite; - NewFile->Protocol.GetPosition = CoreFileGetPosition; - NewFile->Protocol.SetPosition = CoreFileSetPosition; - NewFile->Protocol.GetInfo = CoreFileGetInfo; - NewFile->Protocol.SetInfo = CoreFileSetInfo; - NewFile->Protocol.Flush = CoreFileFlush; - NewFile->Protocol.OpenEx = CoreFileOpenEx; - NewFile->Protocol.ReadEx = CoreFileReadEx; - NewFile->Protocol.WriteEx = CoreFileWriteEx; - NewFile->Protocol.FlushEx = CoreFileFlushEx; - - DisableSMAP (); - NewFile->Ring3File = *Ring3NewHandle; - EnableSMAP (); - - *NewHandle = (EFI_FILE_PROTOCOL *)NewFile; - - CoreFreePages (Ring3Pages, PagesNumber); - - return Status; -} - -EFI_STATUS -EFIAPI -CoreOpenVolume ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, - OUT EFI_FILE_PROTOCOL **Root - ) -{ - EFI_STATUS Status; - EFI_FILE_PROTOCOL **Ring3Root; - RING3_EFI_FILE_PROTOCOL *File; - EFI_PHYSICAL_ADDRESS Physical; - - if (Root == NULL) { - return EFI_INVALID_PARAMETER; - } - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - 1, - &Physical - ); - if (EFI_ERROR (Status)) { - *Root = NULL; - return Status; - } - - Ring3Root = (EFI_FILE_PROTOCOL **)(UINTN)Physical; - - Status = GoToRing3 ( - 2, - (VOID *)mRing3SimpleFileSystemProtocol.OpenVolume, - mRing3SimpleFileSystemPointer, - Ring3Root - ); - if (EFI_ERROR (Status)) { - *Root = NULL; - CoreFreePages (Physical, 1); - return Status; - } - - File = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); - if (File == NULL) { - *Root = NULL; - CoreFreePages (Physical, 1); - return EFI_OUT_OF_RESOURCES; - } - - DisableSMAP (); - mRing3FileProtocol.Revision = (*Ring3Root)->Revision; - mRing3FileProtocol.Open = (*Ring3Root)->Open; - mRing3FileProtocol.Close = (*Ring3Root)->Close; - mRing3FileProtocol.Delete = (*Ring3Root)->Delete; - mRing3FileProtocol.Read = (*Ring3Root)->Read; - mRing3FileProtocol.Write = (*Ring3Root)->Write; - mRing3FileProtocol.GetPosition = (*Ring3Root)->GetPosition; - mRing3FileProtocol.SetPosition = (*Ring3Root)->SetPosition; - mRing3FileProtocol.GetInfo = (*Ring3Root)->GetInfo; - mRing3FileProtocol.SetInfo = (*Ring3Root)->SetInfo; - mRing3FileProtocol.Flush = (*Ring3Root)->Flush; - mRing3FileProtocol.OpenEx = (*Ring3Root)->OpenEx; - mRing3FileProtocol.ReadEx = (*Ring3Root)->ReadEx; - mRing3FileProtocol.WriteEx = (*Ring3Root)->WriteEx; - mRing3FileProtocol.FlushEx = (*Ring3Root)->FlushEx; - - File->Ring3File = *Ring3Root; - EnableSMAP (); - - File->Protocol.Revision = mRing3FileProtocol.Revision; - File->Protocol.Open = CoreFileOpen; - File->Protocol.Close = CoreFileClose; - File->Protocol.Delete = CoreFileDelete; - File->Protocol.Read = CoreFileRead; - File->Protocol.Write = CoreFileWrite; - File->Protocol.GetPosition = CoreFileGetPosition; - File->Protocol.SetPosition = CoreFileSetPosition; - File->Protocol.GetInfo = CoreFileGetInfo; - File->Protocol.SetInfo = CoreFileSetInfo; - File->Protocol.Flush = CoreFileFlush; - File->Protocol.OpenEx = CoreFileOpenEx; - File->Protocol.ReadEx = CoreFileReadEx; - File->Protocol.WriteEx = CoreFileWriteEx; - File->Protocol.FlushEx = CoreFileFlushEx; - - *Root = (EFI_FILE_PROTOCOL *)File; - - CoreFreePages (Physical, 1); - - return Status; -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" + +EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; +EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mRing3SimpleFileSystemProtocol; +EFI_FILE_PROTOCOL mRing3FileProtocol; + +EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; + +#if defined (MDE_CPU_AARCH64) +extern UINTN gUartBaseAddress; +#endif + +typedef struct { + EFI_FILE_PROTOCOL Protocol; + EFI_FILE_PROTOCOL *Ring3File; +} RING3_EFI_FILE_PROTOCOL; + +EFI_STATUS +EFIAPI +GoToRing3 ( + IN UINT8 Number, + IN VOID *EntryPoint, + ... + ) +{ + EFI_STATUS Status; + RING3_CALL_DATA *Input; + VA_LIST Marker; + UINTN Index; + EFI_PHYSICAL_ADDRESS Ring3Pages; + UINT32 PagesNumber; + + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (RING3_CALL_DATA) + Number * sizeof (UINTN)); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + &Ring3Pages + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Input = (RING3_CALL_DATA *)(UINTN)Ring3Pages; + + DisableSMAP (); + Input->NumberOfArguments = Number; + Input->EntryPoint = EntryPoint; + + VA_START (Marker, EntryPoint); + for (Index = 0; Index < Number; ++Index) { + Input->Arguments[Index] = VA_ARG (Marker, UINTN); + } + VA_END (Marker); + EnableSMAP (); + +#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) + if (Number == 2) { + // + // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() + // + SetUefiImageMemoryAttributes ( + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + } +#elif defined (MDE_CPU_AARCH64) + // + // Necessary fix for DEBUG printings. + // + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); +#endif + Status = CallRing3 (Input); + +#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) + if (Number == 2) { + SetUefiImageMemoryAttributes ( + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP + ); + } +#elif defined (MDE_CPU_AARCH64) + // + // Problem 2: Uart memory maped page is not allocated at the very beginnig + // and can be used for translation table later. + // + DisableSMAP (); + // + // Problem 3: QEMU ramdomly breaks GP registers' context. + // + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP + ); + EnableSMAP (); +#endif + + CoreFreePages (Ring3Pages, PagesNumber); + + return Status; +} + +STATIC +VOID * +EFIAPI +Ring3Copy ( + IN VOID *Core, + IN UINT32 Size + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Ring3; + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + 1, + &Ring3 + ); + if (EFI_ERROR (Status)) { + return NULL; + } + + DisableSMAP (); + CopyMem ((VOID *)(UINTN)Ring3, Core, Size); + EnableSMAP (); + + return (VOID *)(UINTN)Ring3; +} + +EFI_STATUS +EFIAPI +CoreDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + EFI_STATUS Status; + + This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); + if (This == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = GoToRing3 ( + 3, + (VOID *)mRing3DriverBindingProtocol.Supported, + This, + ControllerHandle, + RemainingDevicePath + ); + + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); + + return Status; +} + +EFI_STATUS +EFIAPI +CoreDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + EFI_STATUS Status; + + This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); + if (This == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = GoToRing3 ( + 3, + (VOID *)mRing3DriverBindingProtocol.Start, + This, + ControllerHandle, + RemainingDevicePath + ); + + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); + + return Status; +} + +EFI_STATUS +EFIAPI +CoreDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ) +{ + EFI_STATUS Status; + + This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); + if (This == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = GoToRing3 ( + 4, + (VOID *)mRing3DriverBindingProtocol.Stop, + This, + ControllerHandle, + NumberOfChildren, + ChildHandleBuffer + ); + + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); + + return Status; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileClose ( + IN EFI_FILE_PROTOCOL *This + ) +{ + EFI_STATUS Status; + RING3_EFI_FILE_PROTOCOL *File; + + File = (RING3_EFI_FILE_PROTOCOL *)This; + + Status = GoToRing3 ( + 1, + (VOID *)mRing3FileProtocol.Close, + File->Ring3File + ); + + FreePool (This); + + return Status; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileDelete ( + IN EFI_FILE_PROTOCOL *This + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileRead ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + RING3_EFI_FILE_PROTOCOL *File; + UINTN *Ring3BufferSize; + VOID *Ring3Buffer; + EFI_PHYSICAL_ADDRESS Ring3Pages; + UINT32 PagesNumber; + + if ((This == NULL) || (BufferSize == NULL)) { + return EFI_INVALID_PARAMETER; + } + + File = (RING3_EFI_FILE_PROTOCOL *)This; + Ring3Buffer = NULL; + Ring3Pages = 0; + + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + &Ring3Pages + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; + + DisableSMAP (); + *Ring3BufferSize = *BufferSize; + EnableSMAP (); + + if (Buffer != NULL) { + Ring3Buffer = (VOID *)((UINTN *)(UINTN)Ring3Pages + 1); + } + + Status = GoToRing3 ( + 3, + (VOID *)mRing3FileProtocol.Read, + File->Ring3File, + Ring3BufferSize, + Ring3Buffer + ); + + DisableSMAP (); + if ((Ring3Buffer != NULL) && (Buffer != NULL) && (*BufferSize >= *Ring3BufferSize)) { + CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); + } + + *BufferSize = *Ring3BufferSize; + EnableSMAP (); + + CoreFreePages (Ring3Pages, PagesNumber); + + return Status; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileWrite ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileSetPosition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ) +{ + RING3_EFI_FILE_PROTOCOL *File; + + File = (RING3_EFI_FILE_PROTOCOL *)This; + +#if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) + return GoToRing3 ( + 2, + (VOID *)mRing3FileProtocol.SetPosition, + File->Ring3File, + Position + ); +#elif defined (MDE_CPU_IA32) + // + // UINT64 Position is passed as 2 double words on stack. + // + return GoToRing3 ( + 3, + (VOID *)mRing3FileProtocol.SetPosition, + File->Ring3File, + Position + ); +#elif defined (MDE_CPU_ARM) + // + // UINT64 Position is passed as 2 words in 2 registers and is aligned on 8 bytes. + // R0 == File->Ring3File, R1 == NULL, R2 == Position_Low, R3 == Position_High. + // + return GoToRing3 ( + 4, + (VOID *)mRing3FileProtocol.SetPosition, + File->Ring3File, + Position + ); +#endif + +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileGetPosition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ) +{ + EFI_STATUS Status; + RING3_EFI_FILE_PROTOCOL *File; + EFI_PHYSICAL_ADDRESS Ring3Position; + + if ((This == NULL) || (Position == NULL)) { + return EFI_INVALID_PARAMETER; + } + + File = (RING3_EFI_FILE_PROTOCOL *)This; + Ring3Position = 0; + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + 1, + &Ring3Position + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DisableSMAP (); + *(UINT64 *)(UINTN)Ring3Position = *Position; + EnableSMAP (); + + Status = GoToRing3 ( + 2, + (VOID *)mRing3FileProtocol.GetPosition, + File->Ring3File, + Ring3Position + ); + + DisableSMAP (); + *Position = *(UINT64 *)(UINTN)Ring3Position; + EnableSMAP (); + + CoreFreePages (Ring3Position, 1); + + return Status; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileGetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + RING3_EFI_FILE_PROTOCOL *File; + EFI_GUID *Ring3InformationType; + UINTN *Ring3BufferSize; + VOID *Ring3Buffer; + EFI_PHYSICAL_ADDRESS Ring3Pages; + UINT32 PagesNumber; + + if ((This == NULL) || (BufferSize == NULL)) { + return EFI_INVALID_PARAMETER; + } + + File = (RING3_EFI_FILE_PROTOCOL *)This; + Ring3Buffer = NULL; + Ring3InformationType = NULL; + Ring3Pages = 0; + + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize + sizeof (EFI_GUID)); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + &Ring3Pages + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; + + DisableSMAP (); + *Ring3BufferSize = *BufferSize; + EnableSMAP (); + + if (Buffer != NULL) { + Ring3Buffer = (VOID *)((UINTN *)(UINTN)Ring3Pages + 1); + } + + if (InformationType != NULL) { + Ring3InformationType = (EFI_GUID *)((UINTN)Ring3Pages + sizeof (UINTN *) + *BufferSize); + + DisableSMAP (); + CopyGuid (Ring3InformationType, InformationType); + EnableSMAP (); + } + + Status = GoToRing3 ( + 4, + (VOID *)mRing3FileProtocol.GetInfo, + File->Ring3File, + Ring3InformationType, + Ring3BufferSize, + Ring3Buffer + ); + + DisableSMAP (); + if ((Ring3Buffer != NULL) && (Buffer != NULL) && (*BufferSize >= *Ring3BufferSize)) { + CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); + } + + *BufferSize = *Ring3BufferSize; + EnableSMAP (); + + CoreFreePages (Ring3Pages, PagesNumber); + + return Status; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileSetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileFlush ( + IN EFI_FILE_PROTOCOL *This + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileOpenEx ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes, + IN OUT EFI_FILE_IO_TOKEN *Token + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileReadEx ( + IN EFI_FILE_PROTOCOL *This, + IN OUT EFI_FILE_IO_TOKEN *Token + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileWriteEx ( + IN EFI_FILE_PROTOCOL *This, + IN OUT EFI_FILE_IO_TOKEN *Token + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileFlushEx ( + IN EFI_FILE_PROTOCOL *This, + IN OUT EFI_FILE_IO_TOKEN *Token + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileOpen ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ) +{ + EFI_STATUS Status; + RING3_EFI_FILE_PROTOCOL *File; + RING3_EFI_FILE_PROTOCOL *NewFile; + EFI_FILE_PROTOCOL **Ring3NewHandle; + CHAR16 *Ring3FileName; + EFI_PHYSICAL_ADDRESS Ring3Pages; + UINT32 PagesNumber; + + if ((This == NULL) || (NewHandle == NULL) || (FileName == NULL)) { + return EFI_INVALID_PARAMETER; + } + + File = (RING3_EFI_FILE_PROTOCOL *)This; + Ring3NewHandle = NULL; + Ring3FileName = NULL; + Ring3Pages = 0; + + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (EFI_FILE_PROTOCOL *) + StrSize (FileName)); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + &Ring3Pages + ); + if (EFI_ERROR (Status)) { + *NewHandle = NULL; + return Status; + } + + Ring3NewHandle = (EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages; + Ring3FileName = (CHAR16 *)((EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages + 1); + + DisableSMAP (); + Status = StrCpyS (Ring3FileName, StrLen (FileName) + 1, FileName); + EnableSMAP (); + if (EFI_ERROR (Status)) { + *NewHandle = NULL; + CoreFreePages (Ring3Pages, PagesNumber); + return Status; + } + +#if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) + Status = GoToRing3 ( + 5, + (VOID *)mRing3FileProtocol.Open, + File->Ring3File, + Ring3NewHandle, + Ring3FileName, + OpenMode, + Attributes + ); +#elif defined (MDE_CPU_IA32) + // + // UINT64 OpenMode and Attributes are each passed as 2 double words on stack. + // + Status = GoToRing3 ( + 7, + (VOID *)mRing3FileProtocol.Open, + File->Ring3File, + Ring3NewHandle, + Ring3FileName, + OpenMode, + Attributes + ); +#elif defined (MDE_CPU_ARM) + // + // UINT64 OpenMode and Attributes are each passed as 2 words on stack. + // Each of them is aligned on 8 bytes. + // R0 == File->Ring3File, R1 == Ring3NewHandle, R2 == Ring3FileName, R3 == NULL, + // [SP] == OpenMode, [SP + 8] == Attributes. + // + Status = GoToRing3 ( + 8, + (VOID *)mRing3FileProtocol.Open, + File->Ring3File, + Ring3NewHandle, + Ring3FileName, + OpenMode, + Attributes + ); +#endif + if (EFI_ERROR (Status)) { + *NewHandle = NULL; + CoreFreePages (Ring3Pages, PagesNumber); + return Status; + } + + NewFile = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); + if (NewFile == NULL) { + *NewHandle = NULL; + CoreFreePages (Ring3Pages, PagesNumber); + return EFI_OUT_OF_RESOURCES; + } + + NewFile->Protocol.Revision = mRing3FileProtocol.Revision; + NewFile->Protocol.Open = CoreFileOpen; + NewFile->Protocol.Close = CoreFileClose; + NewFile->Protocol.Delete = CoreFileDelete; + NewFile->Protocol.Read = CoreFileRead; + NewFile->Protocol.Write = CoreFileWrite; + NewFile->Protocol.GetPosition = CoreFileGetPosition; + NewFile->Protocol.SetPosition = CoreFileSetPosition; + NewFile->Protocol.GetInfo = CoreFileGetInfo; + NewFile->Protocol.SetInfo = CoreFileSetInfo; + NewFile->Protocol.Flush = CoreFileFlush; + NewFile->Protocol.OpenEx = CoreFileOpenEx; + NewFile->Protocol.ReadEx = CoreFileReadEx; + NewFile->Protocol.WriteEx = CoreFileWriteEx; + NewFile->Protocol.FlushEx = CoreFileFlushEx; + + DisableSMAP (); + NewFile->Ring3File = *Ring3NewHandle; + EnableSMAP (); + + *NewHandle = (EFI_FILE_PROTOCOL *)NewFile; + + CoreFreePages (Ring3Pages, PagesNumber); + + return Status; +} + +EFI_STATUS +EFIAPI +CoreOpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root + ) +{ + EFI_STATUS Status; + EFI_FILE_PROTOCOL **Ring3Root; + RING3_EFI_FILE_PROTOCOL *File; + EFI_PHYSICAL_ADDRESS Physical; + + if (Root == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + 1, + &Physical + ); + if (EFI_ERROR (Status)) { + *Root = NULL; + return Status; + } + + Ring3Root = (EFI_FILE_PROTOCOL **)(UINTN)Physical; + + Status = GoToRing3 ( + 2, + (VOID *)mRing3SimpleFileSystemProtocol.OpenVolume, + mRing3SimpleFileSystemPointer, + Ring3Root + ); + if (EFI_ERROR (Status)) { + *Root = NULL; + CoreFreePages (Physical, 1); + return Status; + } + + File = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); + if (File == NULL) { + *Root = NULL; + CoreFreePages (Physical, 1); + return EFI_OUT_OF_RESOURCES; + } + + DisableSMAP (); + mRing3FileProtocol.Revision = (*Ring3Root)->Revision; + mRing3FileProtocol.Open = (*Ring3Root)->Open; + mRing3FileProtocol.Close = (*Ring3Root)->Close; + mRing3FileProtocol.Delete = (*Ring3Root)->Delete; + mRing3FileProtocol.Read = (*Ring3Root)->Read; + mRing3FileProtocol.Write = (*Ring3Root)->Write; + mRing3FileProtocol.GetPosition = (*Ring3Root)->GetPosition; + mRing3FileProtocol.SetPosition = (*Ring3Root)->SetPosition; + mRing3FileProtocol.GetInfo = (*Ring3Root)->GetInfo; + mRing3FileProtocol.SetInfo = (*Ring3Root)->SetInfo; + mRing3FileProtocol.Flush = (*Ring3Root)->Flush; + mRing3FileProtocol.OpenEx = (*Ring3Root)->OpenEx; + mRing3FileProtocol.ReadEx = (*Ring3Root)->ReadEx; + mRing3FileProtocol.WriteEx = (*Ring3Root)->WriteEx; + mRing3FileProtocol.FlushEx = (*Ring3Root)->FlushEx; + + File->Ring3File = *Ring3Root; + EnableSMAP (); + + File->Protocol.Revision = mRing3FileProtocol.Revision; + File->Protocol.Open = CoreFileOpen; + File->Protocol.Close = CoreFileClose; + File->Protocol.Delete = CoreFileDelete; + File->Protocol.Read = CoreFileRead; + File->Protocol.Write = CoreFileWrite; + File->Protocol.GetPosition = CoreFileGetPosition; + File->Protocol.SetPosition = CoreFileSetPosition; + File->Protocol.GetInfo = CoreFileGetInfo; + File->Protocol.SetInfo = CoreFileSetInfo; + File->Protocol.Flush = CoreFileFlush; + File->Protocol.OpenEx = CoreFileOpenEx; + File->Protocol.ReadEx = CoreFileReadEx; + File->Protocol.WriteEx = CoreFileWriteEx; + File->Protocol.FlushEx = CoreFileFlushEx; + + *Root = (EFI_FILE_PROTOCOL *)File; + + CoreFreePages (Physical, 1); + + return Status; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h index 8f77026355..235d62872d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h @@ -1,48 +1,48 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include -#include -#include -#include -#include - -extern EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; -extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mRing3SimpleFileSystemProtocol; -extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; - -EFI_STATUS -EFIAPI -CoreDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL - ); - -EFI_STATUS -EFIAPI -CoreDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL - ); - -EFI_STATUS -EFIAPI -CoreDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer OPTIONAL - ); - -EFI_STATUS -EFIAPI -CoreOpenVolume ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, - OUT EFI_FILE_PROTOCOL **Root - ); +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include +#include +#include +#include +#include + +extern EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; +extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mRing3SimpleFileSystemProtocol; +extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; + +EFI_STATUS +EFIAPI +CoreDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +EFI_STATUS +EFIAPI +CoreDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +EFI_STATUS +EFIAPI +CoreDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ); + +EFI_STATUS +EFIAPI +CoreOpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root + ); diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index a18680ed6c..cf1bd7c94b 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -1,246 +1,246 @@ -;------------------------------------------------------------------------------ -; -; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -; SPDX-License-Identifier: BSD-3-Clause -; -;------------------------------------------------------------------------------ - -#include - -extern ASM_PFX(CallBootService) -extern ASM_PFX(gCoreSysCallStackTop) -extern ASM_PFX(gRing3CallStackTop) -extern ASM_PFX(gRing3EntryPoint) - -DEFAULT REL -SECTION .text - -;------------------------------------------------------------------------------ -; VOID -; EFIAPI -; DisableSMAP ( -; VOID -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(DisableSMAP) -ASM_PFX(DisableSMAP): - pushfq - pop r10 - or r10, 0x40000 ; Set AC (bit 18) - push r10 - popfq - ret - -;------------------------------------------------------------------------------ -; VOID -; EFIAPI -; EnableSMAP ( -; VOID -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(EnableSMAP) -ASM_PFX(EnableSMAP): - pushfq - pop r10 - and r10, ~0x40000 ; Clear AC (bit 18) - push r10 - popfq - ret - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; CallInstallMultipleProtocolInterfaces ( -; IN EFI_HANDLE *Handle, -; IN VOID **ArgList, -; IN UINT32 ArgListSize, -; IN VOID *Function -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(CallInstallMultipleProtocolInterfaces) -ASM_PFX(CallInstallMultipleProtocolInterfaces): - push r12 - - ; Save function input. - mov rax, rdx - mov r10, r8 - mov r11, r9 - - ; Prepare registers for call. - mov rdx, [rax] - mov r8, [rax + 8] - mov r9, [rax + 8*2] - - ; Prepare stack for call. - lea rax, [rax + r10 * 8] - mov r12, r10 -copy: - sub rax, 8 - push qword [rax] - sub r10, 1 - jnz copy - push rcx - - call r11 - - ; Step over Function arguments. - pop rcx - lea rsp, [rsp + r12 * 8] - - pop r12 - - ret - -%macro SetRing3DataSegmentSelectors 0 - mov rcx, MSR_IA32_STAR - rdmsr - shl rdx, 0x20 - or rax, rdx - ; rax = ((RING3_CODE64_SEL - 16) << 16 | RING0_CODE64_SEL) << 32 - shr rax, 48 - add rax, 8 - - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax -%endmacro - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; CoreBootServices ( -; IN UINT8 Type, -; ... -; ); -; -; (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). -; (rdx) Argument 1 of the called function. -; (r8) Argument 2 of the called function. -; (r9) Argument 3 of the called function. -; (r10) Type. -; (r11) RFLAGS saved by SYSCALL in SysCall(). -; -; (On User Stack) Argument 4, 5, ... -;------------------------------------------------------------------------------ -global ASM_PFX(CoreBootServices) -ASM_PFX(CoreBootServices): - ; Switch from User to Core data segment selectors. - mov ax, ss - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - ; Special case for SysCallReturnToCore. - cmp r10, 0 - je coreReturnAddress - - ; Save User Stack pointers and switch to Core SysCall Stack. - mov rax, [ASM_PFX(gCoreSysCallStackTop)] - sub rax, 8 - mov [rax], rsp - mov rsp, rax - push rbp - ; Save return address for SYSRET. - push rcx - ; Save User RFLAGS for SYSRET. - push r11 - ; Save User Arguments [1..3]. - push r9 - push r8 - push rdx - mov rbp, rsp - - ; Prepare CallBootService arguments. - mov rcx, r10 - mov rdx, rbp - mov r8, [rbp + 8*6] - - sti - call ASM_PFX(CallBootService) - push rax - cli - - SetRing3DataSegmentSelectors - - pop rax - - ; Step over Arguments [1..3]. - add rsp, 8*3 - - ; Prepare SYSRET arguments. - pop r11 - pop rcx - - ; Switch to User Stack. - pop rbp - pop rsp - - ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. -o64 sysret - ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; CallRing3 ( -; IN RING3_CALL_DATA *Data -; ); -; -; (rcx) Data -;------------------------------------------------------------------------------ -global ASM_PFX(CallRing3) -ASM_PFX(CallRing3): - pushfq - pop r11 - cli - ; Save nonvolatile registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15. - push rbx - push rbp - push rdi - push rsi - push r12 - push r13 - push r14 - push r15 - - ; Save Core Stack pointer. - mov [ASM_PFX(CoreRsp)], rsp - - ; Save input Arguments. - mov r8, [ASM_PFX(gRing3CallStackTop)] - mov r9, [ASM_PFX(gRing3EntryPoint)] - mov r10, rcx - - SetRing3DataSegmentSelectors - - ; Prepare SYSRET arguments. - mov rdx, r10 - mov rcx, r9 - - ; Switch to User Stack. - mov rsp, r8 - mov rbp, rsp - - ; Pass control to user image -o64 sysret - -coreReturnAddress: - mov rsp, [ASM_PFX(CoreRsp)] - pop r15 - pop r14 - pop r13 - pop r12 - pop rsi - pop rdi - pop rbp - pop rbx - - mov rax, rdx - sti - ret - -SECTION .data -ASM_PFX(CoreRsp): - resq 1 +;------------------------------------------------------------------------------ +; +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause +; +;------------------------------------------------------------------------------ + +#include + +extern ASM_PFX(CallBootService) +extern ASM_PFX(gCoreSysCallStackTop) +extern ASM_PFX(gRing3CallStackTop) +extern ASM_PFX(gRing3EntryPoint) + +DEFAULT REL +SECTION .text + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; DisableSMAP ( +; VOID +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(DisableSMAP) +ASM_PFX(DisableSMAP): + pushfq + pop r10 + or r10, 0x40000 ; Set AC (bit 18) + push r10 + popfq + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; EnableSMAP ( +; VOID +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(EnableSMAP) +ASM_PFX(EnableSMAP): + pushfq + pop r10 + and r10, ~0x40000 ; Clear AC (bit 18) + push r10 + popfq + ret + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CallInstallMultipleProtocolInterfaces ( +; IN EFI_HANDLE *Handle, +; IN VOID **ArgList, +; IN UINT32 ArgListSize, +; IN VOID *Function +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(CallInstallMultipleProtocolInterfaces) +ASM_PFX(CallInstallMultipleProtocolInterfaces): + push r12 + + ; Save function input. + mov rax, rdx + mov r10, r8 + mov r11, r9 + + ; Prepare registers for call. + mov rdx, [rax] + mov r8, [rax + 8] + mov r9, [rax + 8*2] + + ; Prepare stack for call. + lea rax, [rax + r10 * 8] + mov r12, r10 +copy: + sub rax, 8 + push qword [rax] + sub r10, 1 + jnz copy + push rcx + + call r11 + + ; Step over Function arguments. + pop rcx + lea rsp, [rsp + r12 * 8] + + pop r12 + + ret + +%macro SetRing3DataSegmentSelectors 0 + mov rcx, MSR_IA32_STAR + rdmsr + shl rdx, 0x20 + or rax, rdx + ; rax = ((RING3_CODE64_SEL - 16) << 16 | RING0_CODE64_SEL) << 32 + shr rax, 48 + add rax, 8 + + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax +%endmacro + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CoreBootServices ( +; IN UINT8 Type, +; ... +; ); +; +; (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). +; (rdx) Argument 1 of the called function. +; (r8) Argument 2 of the called function. +; (r9) Argument 3 of the called function. +; (r10) Type. +; (r11) RFLAGS saved by SYSCALL in SysCall(). +; +; (On User Stack) Argument 4, 5, ... +;------------------------------------------------------------------------------ +global ASM_PFX(CoreBootServices) +ASM_PFX(CoreBootServices): + ; Switch from User to Core data segment selectors. + mov ax, ss + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + ; Special case for SysCallReturnToCore. + cmp r10, 0 + je coreReturnAddress + + ; Save User Stack pointers and switch to Core SysCall Stack. + mov rax, [ASM_PFX(gCoreSysCallStackTop)] + sub rax, 8 + mov [rax], rsp + mov rsp, rax + push rbp + ; Save return address for SYSRET. + push rcx + ; Save User RFLAGS for SYSRET. + push r11 + ; Save User Arguments [1..3]. + push r9 + push r8 + push rdx + mov rbp, rsp + + ; Prepare CallBootService arguments. + mov rcx, r10 + mov rdx, rbp + mov r8, [rbp + 8*6] + + sti + call ASM_PFX(CallBootService) + push rax + cli + + SetRing3DataSegmentSelectors + + pop rax + + ; Step over Arguments [1..3]. + add rsp, 8*3 + + ; Prepare SYSRET arguments. + pop r11 + pop rcx + + ; Switch to User Stack. + pop rbp + pop rsp + + ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. +o64 sysret + ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CallRing3 ( +; IN RING3_CALL_DATA *Data +; ); +; +; (rcx) Data +;------------------------------------------------------------------------------ +global ASM_PFX(CallRing3) +ASM_PFX(CallRing3): + pushfq + pop r11 + cli + ; Save nonvolatile registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15. + push rbx + push rbp + push rdi + push rsi + push r12 + push r13 + push r14 + push r15 + + ; Save Core Stack pointer. + mov [ASM_PFX(CoreRsp)], rsp + + ; Save input Arguments. + mov r8, [ASM_PFX(gRing3CallStackTop)] + mov r9, [ASM_PFX(gRing3EntryPoint)] + mov r10, rcx + + SetRing3DataSegmentSelectors + + ; Prepare SYSRET arguments. + mov rdx, r10 + mov rcx, r9 + + ; Switch to User Stack. + mov rsp, r8 + mov rbp, rsp + + ; Pass control to user image +o64 sysret + +coreReturnAddress: + mov rsp, [ASM_PFX(CoreRsp)] + pop r15 + pop r14 + pop r13 + pop r12 + pop rsi + pop rdi + pop rbp + pop rbx + + mov rax, rdx + sti + ret + +SECTION .data +ASM_PFX(CoreRsp): + resq 1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c index 348d850f1c..9694c071c2 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c @@ -1,70 +1,70 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include "DxeMain.h" - -#include - -VOID -EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries - ) -{ - UINT64 Msr; - IA32_CR4 Cr4; - IA32_EFLAGS32 Eflags; - UINT32 Ebx; - UINT32 Edx; - MSR_IA32_EFER_REGISTER MsrEfer; - - Ebx = 0; - Edx = 0; - - // - // Forbid supervisor-mode accesses to any user-mode pages. - // - AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); - if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) { - Cr4.UintN = AsmReadCr4 (); - Cr4.Bits.SMAP = 1; - Cr4.Bits.SMEP = 1; - AsmWriteCr4 (Cr4.UintN); - - Eflags.UintN = AsmReadEflags (); - Eflags.Bits.AC = 0; - AsmWriteEflags (Eflags.UintN); - } - - // - // Enable SYSCALL and SYSRET. - // - AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx); - if ((Edx & BIT11) != 0) { - MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); - MsrEfer.Bits.SCE = 1; - AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64); - } else { - DEBUG ((DEBUG_ERROR, "Core: SYSCALL and SYSRET are not supported.\n")); - CpuDeadLoop (); - } - - // - // Initialize MSR_IA32_STAR, MSR_IA32_LSTAR and MSR_IA32_FMASK for SYSCALL and SYSRET. - // - Msr = (((((UINT64)RING3_CODE64_SEL - 16) | 3) << 16) | (UINT64)RING0_CODE64_SEL) << 32; - AsmWriteMsr64 (MSR_IA32_STAR, Msr); - - Msr = (UINT64)(UINTN)CoreBootServices; - AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); - // - // Disable maskable interrupts at SYSCALL. - // - Msr = (UINT64)BIT9; - AsmWriteMsr64 (MSR_IA32_FMASK, Msr); -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" + +#include + +VOID +EFIAPI +InitializeMsr ( + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries + ) +{ + UINT64 Msr; + IA32_CR4 Cr4; + IA32_EFLAGS32 Eflags; + UINT32 Ebx; + UINT32 Edx; + MSR_IA32_EFER_REGISTER MsrEfer; + + Ebx = 0; + Edx = 0; + + // + // Forbid supervisor-mode accesses to any user-mode pages. + // + AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); + if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) { + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.SMAP = 1; + Cr4.Bits.SMEP = 1; + AsmWriteCr4 (Cr4.UintN); + + Eflags.UintN = AsmReadEflags (); + Eflags.Bits.AC = 0; + AsmWriteEflags (Eflags.UintN); + } + + // + // Enable SYSCALL and SYSRET. + // + AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx); + if ((Edx & BIT11) != 0) { + MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); + MsrEfer.Bits.SCE = 1; + AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64); + } else { + DEBUG ((DEBUG_ERROR, "Core: SYSCALL and SYSRET are not supported.\n")); + CpuDeadLoop (); + } + + // + // Initialize MSR_IA32_STAR, MSR_IA32_LSTAR and MSR_IA32_FMASK for SYSCALL and SYSRET. + // + Msr = (((((UINT64)RING3_CODE64_SEL - 16) | 3) << 16) | (UINT64)RING0_CODE64_SEL) << 32; + AsmWriteMsr64 (MSR_IA32_STAR, Msr); + + Msr = (UINT64)(UINTN)CoreBootServices; + AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); + // + // Disable maskable interrupts at SYSCALL. + // + Msr = (UINT64)BIT9; + AsmWriteMsr64 (MSR_IA32_FMASK, Msr); +}