mirror of
https://github.com/acidanthera/audk.git
synced 2025-08-23 02:28:08 +02:00
1476 lines
50 KiB
C
1476 lines
50 KiB
C
/** @file
|
|
|
|
Copyright (c) 2024 - 2025, 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 *UserSpace;
|
|
LIST_ENTRY Link;
|
|
} INTERFACE;
|
|
|
|
UINTN mUserSpaceInterfacePointer = 0;
|
|
|
|
CHAR8 *SysCallNames[] = {
|
|
//
|
|
// BootServices
|
|
//
|
|
"SysCallReturnToCore",
|
|
"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 UINTN ArgListSize,
|
|
IN VOID *Function
|
|
);
|
|
|
|
VOID
|
|
EFIAPI
|
|
ReturnToCore (
|
|
IN EFI_STATUS Status,
|
|
IN UINTN ReturnSP
|
|
);
|
|
|
|
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 *UserSpace,
|
|
OUT EFI_GUID **Core,
|
|
OUT UINT32 *CoreSize
|
|
)
|
|
{
|
|
ASSERT (UserSpace != NULL);
|
|
ASSERT (Core != NULL);
|
|
ASSERT (CoreSize != NULL);
|
|
|
|
if (CompareGuid (UserSpace, &gEfiDevicePathUtilitiesProtocolGuid)) {
|
|
|
|
*Core = &gEfiDevicePathUtilitiesProtocolGuid;
|
|
*CoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL);
|
|
|
|
} else if (CompareGuid (UserSpace, &gEfiLoadedImageProtocolGuid)) {
|
|
|
|
*Core = &gEfiLoadedImageProtocolGuid;
|
|
*CoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL);
|
|
|
|
} else if (CompareGuid (UserSpace, &gEfiBlockIoProtocolGuid)) {
|
|
|
|
*Core = &gEfiBlockIoProtocolGuid;
|
|
*CoreSize = sizeof (EFI_BLOCK_IO_PROTOCOL);
|
|
|
|
} else if (CompareGuid (UserSpace, &gEfiDiskIoProtocolGuid)) {
|
|
|
|
*Core = &gEfiDiskIoProtocolGuid;
|
|
*CoreSize = sizeof (EFI_DISK_IO_PROTOCOL);
|
|
|
|
} else if (CompareGuid (UserSpace, &gEfiDriverBindingProtocolGuid)) {
|
|
|
|
*Core = &gEfiDriverBindingProtocolGuid;
|
|
*CoreSize = sizeof (EFI_DRIVER_BINDING_PROTOCOL);
|
|
|
|
} else if (CompareGuid (UserSpace, &gEfiComponentNameProtocolGuid)) {
|
|
|
|
*Core = &gEfiComponentNameProtocolGuid;
|
|
*CoreSize = sizeof (EFI_COMPONENT_NAME_PROTOCOL);
|
|
|
|
} else if (CompareGuid (UserSpace, &gEfiComponentName2ProtocolGuid)) {
|
|
|
|
*Core = &gEfiComponentName2ProtocolGuid;
|
|
*CoreSize = sizeof (EFI_COMPONENT_NAME2_PROTOCOL);
|
|
|
|
} else if (CompareGuid (UserSpace, &gEfiDevicePathProtocolGuid)) {
|
|
|
|
*Core = &gEfiDevicePathProtocolGuid;
|
|
*CoreSize = sizeof (EFI_DEVICE_PATH_PROTOCOL);
|
|
|
|
} else if (CompareGuid (UserSpace, &gEfiSimpleFileSystemProtocolGuid)) {
|
|
|
|
*Core = &gEfiSimpleFileSystemProtocolGuid;
|
|
*CoreSize = sizeof (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL);
|
|
|
|
} else if (CompareGuid (UserSpace, &gEfiUnicodeCollationProtocolGuid)) {
|
|
|
|
*Core = &gEfiUnicodeCollationProtocolGuid;
|
|
*CoreSize = sizeof (EFI_UNICODE_COLLATION_PROTOCOL);
|
|
|
|
} else if (CompareGuid (UserSpace, &gEfiGlobalVariableGuid)) {
|
|
|
|
*Core = &gEfiGlobalVariableGuid;
|
|
|
|
} else if (CompareGuid (UserSpace, &gEfiUnicodeCollation2ProtocolGuid)) {
|
|
|
|
*Core = &gEfiUnicodeCollation2ProtocolGuid;
|
|
*CoreSize = sizeof (EFI_UNICODE_COLLATION_PROTOCOL);
|
|
|
|
} else {
|
|
DEBUG ((DEBUG_ERROR, "Core: Unknown protocol - %g.\n", UserSpace));
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
STATIC
|
|
VOID *
|
|
EFIAPI
|
|
FindInterface (
|
|
IN BOOLEAN FindUserSpace,
|
|
IN VOID *Interface
|
|
)
|
|
{
|
|
LIST_ENTRY *Link;
|
|
INTERFACE *Protocol;
|
|
|
|
for (Link = mProtocolsHead.ForwardLink; Link != &mProtocolsHead; Link = Link->ForwardLink) {
|
|
Protocol = BASE_CR (Link, INTERFACE, Link);
|
|
|
|
if (FindUserSpace) {
|
|
if (Protocol->Core == Interface) {
|
|
return Protocol->UserSpace;
|
|
}
|
|
} else {
|
|
if (Protocol->UserSpace == Interface) {
|
|
return Protocol->Core;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
STATIC
|
|
VOID *
|
|
EFIAPI
|
|
PrepareUserSpaceInterface (
|
|
IN EFI_GUID *Guid,
|
|
IN VOID *CoreInterface,
|
|
IN UINT32 CoreSize
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN UserSpaceLimit;
|
|
VOID *UserSpaceInterface;
|
|
EFI_BLOCK_IO_PROTOCOL *BlockIo;
|
|
EFI_UNICODE_COLLATION_PROTOCOL *Unicode;
|
|
INTERFACE *Protocol;
|
|
|
|
ASSERT (Guid != NULL);
|
|
ASSERT (CoreInterface != NULL);
|
|
|
|
if (mUserSpaceInterfacePointer == 0) {
|
|
mUserSpaceInterfacePointer = (UINTN)gUserSpaceInterfaces;
|
|
}
|
|
|
|
UserSpaceInterface = FindInterface (TRUE, CoreInterface);
|
|
|
|
if (UserSpaceInterface != NULL) {
|
|
return UserSpaceInterface;
|
|
}
|
|
|
|
UserSpaceLimit = (UINTN)gUserSpaceInterfaces + EFI_PAGES_TO_SIZE (USER_SPACE_INTERFACES_PAGES);
|
|
|
|
ASSERT ((mUserSpaceInterfacePointer + CoreSize) <= UserSpaceLimit);
|
|
|
|
UserSpaceInterface = (VOID *)mUserSpaceInterfacePointer;
|
|
|
|
CopyMem ((VOID *)mUserSpaceInterfacePointer, CoreInterface, CoreSize);
|
|
mUserSpaceInterfacePointer += CoreSize;
|
|
|
|
Protocol = AllocatePool (sizeof (INTERFACE));
|
|
|
|
Protocol->Core = CoreInterface;
|
|
Protocol->UserSpace = UserSpaceInterface;
|
|
|
|
InsertTailList (&mProtocolsHead, &Protocol->Link);
|
|
|
|
if (CompareGuid (Guid, &gEfiBlockIoProtocolGuid)) {
|
|
ASSERT ((mUserSpaceInterfacePointer + sizeof (EFI_BLOCK_IO_MEDIA)) <= UserSpaceLimit);
|
|
|
|
BlockIo = (EFI_BLOCK_IO_PROTOCOL *)UserSpaceInterface;
|
|
|
|
CopyMem ((VOID *)mUserSpaceInterfacePointer, (VOID *)BlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA));
|
|
|
|
BlockIo->Media = (EFI_BLOCK_IO_MEDIA *)mUserSpaceInterfacePointer;
|
|
|
|
mUserSpaceInterfacePointer += sizeof (EFI_BLOCK_IO_MEDIA);
|
|
} else if (CompareGuid (Guid, &gEfiUnicodeCollationProtocolGuid)) {
|
|
|
|
Unicode = (EFI_UNICODE_COLLATION_PROTOCOL *)UserSpaceInterface;
|
|
|
|
ASSERT ((mUserSpaceInterfacePointer + AsciiStrSize (Unicode->SupportedLanguages)) <= UserSpaceLimit);
|
|
|
|
Status = AsciiStrCpyS (
|
|
(CHAR8 *)mUserSpaceInterfacePointer,
|
|
AsciiStrSize (Unicode->SupportedLanguages),
|
|
Unicode->SupportedLanguages
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "Could not copy string!\n"));
|
|
return NULL;
|
|
}
|
|
|
|
Unicode->SupportedLanguages = (CHAR8 *)mUserSpaceInterfacePointer;
|
|
|
|
mUserSpaceInterfacePointer += AsciiStrSize (Unicode->SupportedLanguages);
|
|
}
|
|
|
|
return UserSpaceInterface;
|
|
}
|
|
|
|
STATIC
|
|
UINTN *
|
|
EFIAPI
|
|
CopyUserArguments (
|
|
IN UINT8 NumberOfArguments,
|
|
IN UINTN *UserArguments
|
|
)
|
|
{
|
|
UINTN *Arguments;
|
|
UINT64 Attributes;
|
|
//
|
|
// Check User variables.
|
|
//
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArguments, &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserArguments + (NumberOfArguments + 1) * sizeof (UINTN) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
Arguments = AllocateCopyPool (
|
|
(NumberOfArguments + 1) * sizeof (UINTN),
|
|
(VOID *)UserArguments
|
|
);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
return Arguments;
|
|
}
|
|
|
|
STATIC
|
|
VOID
|
|
EFIAPI
|
|
FreeUserSpaceDriver (
|
|
IN VOID *CoreWrapper
|
|
)
|
|
{
|
|
LIST_ENTRY *Link;
|
|
USER_SPACE_DRIVER *UserDriver;
|
|
|
|
for (Link = gUserSpaceDriversHead.ForwardLink; Link != &gUserSpaceDriversHead; Link = Link->ForwardLink) {
|
|
UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link);
|
|
|
|
if (UserDriver->CoreWrapper == CoreWrapper) {
|
|
RemoveEntryList (&UserDriver->Link);
|
|
FreePool (UserDriver);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
CallBootService (
|
|
IN UINT8 Type,
|
|
IN UINT8 NumberOfArguments,
|
|
IN UINTN *UserArguments,
|
|
IN UINTN ReturnSP
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_STATUS StatusBS;
|
|
UINT64 Attributes;
|
|
VOID *Interface;
|
|
EFI_GUID *CoreProtocol;
|
|
UINT32 MemoryCoreSize;
|
|
UINTN Argument4;
|
|
UINTN Argument5;
|
|
UINTN Argument6;
|
|
UINTN Index;
|
|
VOID **UserArgList;
|
|
VOID **CoreArgList;
|
|
EFI_HANDLE CoreHandle;
|
|
UINT32 PagesNumber;
|
|
EFI_PHYSICAL_ADDRESS UserSpacePages;
|
|
USER_SPACE_DRIVER *NewDriver;
|
|
UINTN *Arguments;
|
|
EFI_PHYSICAL_ADDRESS PhysAddr;
|
|
|
|
EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding;
|
|
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *CoreSimpleFileSystem;
|
|
EFI_UNICODE_COLLATION_PROTOCOL *CoreUnicodeCollation;
|
|
|
|
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;
|
|
Arguments = CopyUserArguments (NumberOfArguments, UserArguments);
|
|
|
|
if (Arguments == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
DEBUG ((DEBUG_VERBOSE, "Type: %a\n", SysCallNames[Type]));
|
|
|
|
switch (Type) {
|
|
case SysCallReturnToCore:
|
|
//
|
|
// Argument 1: EFI_STATUS Status
|
|
// Argument 2: UINTN ReturnSP
|
|
//
|
|
Status = (EFI_STATUS)Arguments[1];
|
|
|
|
FreePool (Arguments);
|
|
|
|
ReturnToCore (Status, ReturnSP);
|
|
break;
|
|
case SysCallLocateProtocol:
|
|
//
|
|
// Argument 1: EFI_GUID *Protocol
|
|
// Argument 2: VOID *CoreRegistration
|
|
// Argument 3: VOID **Interface
|
|
//
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[1], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[1] + sizeof (EFI_GUID) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + sizeof (VOID *) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
Status = FindGuid ((EFI_GUID *)Arguments[1], &CoreProtocol, &MemoryCoreSize);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
if (EFI_ERROR (Status)) {
|
|
break;
|
|
}
|
|
|
|
Status = gBS->LocateProtocol (
|
|
CoreProtocol,
|
|
(VOID *)Arguments[2],
|
|
&Interface
|
|
);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
if (Interface != NULL) {
|
|
Interface = PrepareUserSpaceInterface (CoreProtocol, Interface, MemoryCoreSize);
|
|
ASSERT (Interface != NULL);
|
|
|
|
*(VOID **)Arguments[3] = Interface;
|
|
}
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
break;
|
|
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)Arguments[2], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + sizeof (EFI_GUID) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
if ((VOID **)Arguments[3] != NULL) {
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + sizeof (VOID *) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
}
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
Status = FindGuid ((EFI_GUID *)Arguments[2], &CoreProtocol, &MemoryCoreSize);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
if (EFI_ERROR (Status)) {
|
|
break;
|
|
}
|
|
|
|
Status = gBS->OpenProtocol (
|
|
(EFI_HANDLE)Arguments[1],
|
|
CoreProtocol,
|
|
((VOID **)Arguments[3] != NULL) ? &Interface : NULL,
|
|
(EFI_HANDLE)Arguments[4],
|
|
(EFI_HANDLE)Arguments[5],
|
|
(UINT32)Arguments[6]
|
|
);
|
|
|
|
if ((VOID **)Arguments[3] != NULL) {
|
|
AllowSupervisorAccessToUserMemory ();
|
|
if (Interface != NULL) {
|
|
Interface = PrepareUserSpaceInterface (CoreProtocol, Interface, MemoryCoreSize);
|
|
}
|
|
|
|
*(VOID **)Arguments[3] = Interface;
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
}
|
|
|
|
break;
|
|
case SysCallInstallMultipleProtocolInterfaces:
|
|
//
|
|
// Argument 1: EFI_HANDLE *Handle
|
|
// Argument 2: UINTN NumberOfArguments
|
|
// Argument 3: VOID **UserArgList
|
|
//
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[1], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[1] + sizeof (EFI_HANDLE *) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + Arguments[2] * sizeof (VOID *) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
CoreArgList = AllocatePool (Arguments[2] * sizeof (VOID *));
|
|
if (CoreArgList == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
CoreHandle = *(EFI_HANDLE *)Arguments[1];
|
|
UserArgList = (VOID **)Arguments[3];
|
|
|
|
for (Index = 0; UserArgList[Index] != NULL; Index += 2) {
|
|
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)) {
|
|
goto Exit;
|
|
}
|
|
|
|
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]);
|
|
if (CoreArgList[Index + 1] == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Exit;
|
|
}
|
|
|
|
NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER));
|
|
if (NewDriver == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Exit;
|
|
}
|
|
|
|
NewDriver->CoreWrapper = CoreArgList[Index + 1];
|
|
NewDriver->UserSpaceDriver = UserArgList[Index + 1];
|
|
NewDriver->UserPageTable = gUserPageTable;
|
|
NewDriver->NumberOfCalls = 0;
|
|
|
|
InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link);
|
|
}
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
ASSERT (Index == (Arguments[2] - 1));
|
|
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];
|
|
|
|
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];
|
|
|
|
CoreSimpleFileSystem->OpenVolume = CoreSimpleFileSystemOpenVolume;
|
|
} else if ((CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiUnicodeCollationProtocolGuid))
|
|
|| (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiUnicodeCollation2ProtocolGuid))) {
|
|
CoreUnicodeCollation = (EFI_UNICODE_COLLATION_PROTOCOL *)CoreArgList[Index + 1];
|
|
|
|
CoreUnicodeCollation->StriColl = CoreUnicodeCollationStriColl;
|
|
CoreUnicodeCollation->MetaiMatch = CoreUnicodeCollationMetaiMatch;
|
|
CoreUnicodeCollation->StrLwr = CoreUnicodeCollationStrLwr;
|
|
CoreUnicodeCollation->StrUpr = CoreUnicodeCollationStrUpr;
|
|
CoreUnicodeCollation->FatToStr = CoreUnicodeCollationFatToStr;
|
|
CoreUnicodeCollation->StrToFat = CoreUnicodeCollationStrToFat;
|
|
AllowSupervisorAccessToUserMemory ();
|
|
CoreUnicodeCollation->SupportedLanguages = AllocateCopyPool (
|
|
AsciiStrSize (CoreUnicodeCollation->SupportedLanguages),
|
|
(VOID *)CoreUnicodeCollation->SupportedLanguages
|
|
);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
if (CoreUnicodeCollation->SupportedLanguages == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
Index = Arguments[2] - 1;
|
|
goto Exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
Status = CallInstallMultipleProtocolInterfaces (
|
|
&CoreHandle,
|
|
CoreArgList,
|
|
Arguments[2],
|
|
(VOID *)gBS->InstallMultipleProtocolInterfaces
|
|
);
|
|
|
|
FreePool (CoreArgList);
|
|
break;
|
|
|
|
Exit:
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
while (Index > 0) {
|
|
FreeUserSpaceDriver (CoreArgList[Index - 1]);
|
|
FreePool (CoreArgList[Index - 1]);
|
|
Index -= 2;
|
|
}
|
|
|
|
FreePool (CoreArgList);
|
|
break;
|
|
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)Arguments[2], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + sizeof (EFI_GUID) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
Status = FindGuid ((EFI_GUID *)Arguments[2], &CoreProtocol, &MemoryCoreSize);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
if (EFI_ERROR (Status)) {
|
|
break;
|
|
}
|
|
|
|
Status = gBS->CloseProtocol (
|
|
(EFI_HANDLE)Arguments[1],
|
|
CoreProtocol,
|
|
(EFI_HANDLE)Arguments[3],
|
|
(EFI_HANDLE)Arguments[4]
|
|
);
|
|
|
|
break;
|
|
case SysCallHandleProtocol:
|
|
//
|
|
// Argument 1: EFI_HANDLE CoreUserHandle
|
|
// Argument 2: EFI_GUID *Protocol
|
|
// Argument 3: VOID **Interface
|
|
//
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + sizeof (EFI_GUID) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + sizeof (VOID *) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
Status = FindGuid ((EFI_GUID *)Arguments[2], &CoreProtocol, &MemoryCoreSize);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
if (EFI_ERROR (Status)) {
|
|
break;
|
|
}
|
|
|
|
Status = gBS->HandleProtocol (
|
|
(EFI_HANDLE)Arguments[1],
|
|
CoreProtocol,
|
|
&Interface
|
|
);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
if (Interface != NULL) {
|
|
Interface = PrepareUserSpaceInterface (CoreProtocol, Interface, MemoryCoreSize);
|
|
ASSERT (Interface != NULL);
|
|
|
|
*(VOID **)Arguments[3] = Interface;
|
|
}
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
break;
|
|
case SysCallAllocatePages:
|
|
//
|
|
// Argument 1: EFI_ALLOCATE_TYPE Type
|
|
// Argument 2: EFI_MEMORY_TYPE MemoryType
|
|
// Argument 3: UINTN NumberOfPages
|
|
// Argument 4: EFI_PHYSICAL_ADDRESS *Memory
|
|
//
|
|
Status = gBS->AllocatePages (
|
|
(EFI_ALLOCATE_TYPE)Arguments[1],
|
|
(EFI_MEMORY_TYPE)Arguments[2],
|
|
Arguments[3],
|
|
(EFI_PHYSICAL_ADDRESS *)&Argument4
|
|
);
|
|
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + sizeof (EFI_PHYSICAL_ADDRESS) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
*(EFI_PHYSICAL_ADDRESS *)Arguments[4] = (EFI_PHYSICAL_ADDRESS)Argument4;
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
break;
|
|
case SysCallFreePages:
|
|
//
|
|
// Argument 1: UINTN NumberOfPages
|
|
// Argument 2: EFI_PHYSICAL_ADDRESS Memory
|
|
//
|
|
PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[2];
|
|
|
|
gCpu->GetMemoryAttributes (gCpu, PhysAddr, &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, PhysAddr + Arguments[1] * EFI_PAGE_SIZE - 1, &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
Status = gBS->FreePages (PhysAddr, Arguments[1]);
|
|
|
|
break;
|
|
case SysCallRaiseTpl:
|
|
//
|
|
// Argument 1: EFI_TPL NewTpl
|
|
//
|
|
Status = (EFI_STATUS)gBS->RaiseTPL ((EFI_TPL)Arguments[1]);
|
|
|
|
break;
|
|
case SysCallRestoreTpl:
|
|
//
|
|
// Argument 1: EFI_TPL NewTpl
|
|
//
|
|
gBS->RestoreTPL ((EFI_TPL)Arguments[1]);
|
|
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
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 *)Arguments[2] != NULL) {
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + sizeof (EFI_GUID) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
Status = FindGuid ((EFI_GUID *)Arguments[2], &CoreProtocol, &MemoryCoreSize);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
if (EFI_ERROR (Status)) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
StatusBS = gBS->LocateHandleBuffer (
|
|
(EFI_LOCATE_SEARCH_TYPE)Arguments[1],
|
|
CoreProtocol,
|
|
(VOID *)Arguments[3],
|
|
&Argument4,
|
|
(EFI_HANDLE **)&Argument5
|
|
);
|
|
|
|
if ((UINTN *)Arguments[4] != NULL) {
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + sizeof (UINTN) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
*(UINTN *)Arguments[4] = Argument4;
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
}
|
|
|
|
if ((EFI_HANDLE **)Arguments[5] != NULL) {
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[5], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(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,
|
|
EfiUserSpaceMemoryType,
|
|
PagesNumber,
|
|
&UserSpacePages
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
break;
|
|
}
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
CopyMem ((VOID *)(UINTN)UserSpacePages, (VOID *)Argument5, Argument4 * sizeof (EFI_HANDLE *));
|
|
|
|
FreePool ((VOID *)Argument5);
|
|
|
|
*(EFI_HANDLE **)Arguments[5] = (EFI_HANDLE *)(UINTN)UserSpacePages;
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
}
|
|
|
|
Status = StatusBS;
|
|
break;
|
|
case SysCallCalculateCrc32:
|
|
//
|
|
// Argument 1: VOID *Data
|
|
// Argument 2: UINTN DataSize
|
|
// Argument 3: UINT32 *Crc32
|
|
//
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[1], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[1] + Arguments[2] - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + sizeof (UINT32 *) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
Argument4 = (UINTN)AllocatePool (Arguments[2]);
|
|
if ((VOID *)Argument4 == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
CopyMem ((VOID *)Argument4, (VOID *)Arguments[1], Arguments[2]);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
Status = gBS->CalculateCrc32 (
|
|
(VOID *)Argument4,
|
|
Arguments[2],
|
|
(UINT32 *)&Argument5
|
|
);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
*(UINT32 *)Arguments[3] = (UINT32)Argument5;
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
break;
|
|
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)Arguments[1], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + sizeof (EFI_GUID) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
if ((UINT32 *)Arguments[3] != NULL) {
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + sizeof (UINT32) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
}
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[1] + StrSize ((CHAR16 *)Arguments[1]) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
Argument6 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[1]), (CHAR16 *)Arguments[1]);
|
|
if ((VOID *)Argument6 == NULL) {
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
|
|
Status = FindGuid ((EFI_GUID *)Arguments[2], &CoreProtocol, &MemoryCoreSize);
|
|
if (EFI_ERROR (Status)) {
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
FreePool ((VOID *)Argument6);
|
|
break;
|
|
}
|
|
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + sizeof (UINTN) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
Argument4 = *(UINTN *)Arguments[4];
|
|
|
|
if ((VOID *)Arguments[5] != NULL) {
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[5], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[5] + Argument4 - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
Argument5 = (UINTN)AllocatePool (Argument4);
|
|
if ((VOID *)Argument5 == NULL) {
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
FreePool ((VOID *)Argument6);
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
}
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
Status = gRT->GetVariable (
|
|
(CHAR16 *)Argument6,
|
|
CoreProtocol,
|
|
(UINT32 *)&Attributes,
|
|
&Argument4,
|
|
(VOID *)Argument5
|
|
);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
if ((VOID *)Arguments[5] != NULL) {
|
|
CopyMem ((VOID *)Arguments[5], (VOID *)Argument5, Argument4);
|
|
}
|
|
|
|
*(UINTN *)Arguments[4] = Argument4;
|
|
|
|
if ((UINT32 *)Arguments[3] != NULL) {
|
|
*(UINT32 *)Arguments[3] = (UINT32)Attributes;
|
|
}
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
FreePool ((VOID *)Argument6);
|
|
|
|
if ((VOID *)Argument5 != NULL) {
|
|
FreePool ((VOID *)Argument5);
|
|
}
|
|
|
|
break;
|
|
case SysCallBlockIoReset:
|
|
//
|
|
// Argument 1: EFI_BLOCK_IO_PROTOCOL *This
|
|
// Argument 2: BOOLEAN ExtendedVerification
|
|
//
|
|
BlockIo = FindInterface (FALSE, (VOID *)Arguments[1]);
|
|
|
|
if (BlockIo == NULL) {
|
|
Status = EFI_NOT_FOUND;
|
|
break;
|
|
}
|
|
|
|
Status = BlockIo->Reset (
|
|
BlockIo,
|
|
(BOOLEAN)Arguments[2]
|
|
);
|
|
|
|
break;
|
|
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
|
|
//
|
|
PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[5];
|
|
|
|
BlockIo = FindInterface (FALSE, (VOID *)Arguments[1]);
|
|
|
|
if (BlockIo == NULL) {
|
|
Status = EFI_NOT_FOUND;
|
|
break;
|
|
}
|
|
|
|
Argument5 = (UINTN)AllocatePool (Arguments[3]);
|
|
if ((VOID *)Argument5 == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
|
|
Status = BlockIo->ReadBlocks (
|
|
BlockIo,
|
|
(UINT32)Arguments[2],
|
|
(EFI_LBA)PhysAddr,
|
|
Arguments[3],
|
|
(VOID *)Argument5
|
|
);
|
|
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + Arguments[3] - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
CopyMem ((VOID *)Arguments[4], (VOID *)Argument5, Arguments[3]);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
FreePool ((VOID *)Argument5);
|
|
|
|
break;
|
|
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
|
|
//
|
|
PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[5];
|
|
|
|
BlockIo = FindInterface (FALSE, (VOID *)Arguments[1]);
|
|
|
|
if (BlockIo == NULL) {
|
|
Status = EFI_NOT_FOUND;
|
|
break;
|
|
}
|
|
|
|
Argument5 = (UINTN)AllocatePool (Arguments[3]);
|
|
if ((VOID *)Argument5 == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + Arguments[3] - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
CopyMem ((VOID *)Argument5, (VOID *)Arguments[4], Arguments[3]);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
Status = BlockIo->WriteBlocks (
|
|
BlockIo,
|
|
(UINT32)Arguments[2],
|
|
(EFI_LBA)PhysAddr,
|
|
Arguments[3],
|
|
(VOID *)Argument5
|
|
);
|
|
|
|
FreePool ((VOID *)Argument5);
|
|
|
|
break;
|
|
case SysCallBlockIoFlush:
|
|
//
|
|
// Argument 1: EFI_BLOCK_IO_PROTOCOL *This
|
|
//
|
|
BlockIo = FindInterface (FALSE, (VOID *)Arguments[1]);
|
|
|
|
if (BlockIo == NULL) {
|
|
Status = EFI_NOT_FOUND;
|
|
break;
|
|
}
|
|
|
|
Status = BlockIo->FlushBlocks (BlockIo);
|
|
|
|
break;
|
|
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
|
|
//
|
|
PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[5];
|
|
|
|
DiskIo = FindInterface (FALSE, (VOID *)Arguments[1]);
|
|
|
|
if (DiskIo == NULL) {
|
|
Status = EFI_NOT_FOUND;
|
|
break;
|
|
}
|
|
|
|
Argument5 = (UINTN)AllocatePool (Arguments[3]);
|
|
if ((VOID *)Argument5 == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
|
|
Status = DiskIo->ReadDisk (
|
|
DiskIo,
|
|
(UINT32)Arguments[2],
|
|
(UINT64)PhysAddr,
|
|
Arguments[3],
|
|
(VOID *)Argument5
|
|
);
|
|
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + Arguments[3] - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
CopyMem ((VOID *)Arguments[4], (VOID *)Argument5, Arguments[3]);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
FreePool ((VOID *)Argument5);
|
|
|
|
break;
|
|
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
|
|
//
|
|
PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[5];
|
|
|
|
DiskIo = FindInterface (FALSE, (VOID *)Arguments[1]);
|
|
|
|
if (DiskIo == NULL) {
|
|
Status = EFI_NOT_FOUND;
|
|
break;
|
|
}
|
|
|
|
Argument5 = (UINTN)AllocatePool (Arguments[3]);
|
|
if ((VOID *)Argument5 == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + Arguments[3] - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
CopyMem ((VOID *)Argument5, (VOID *)Arguments[4], Arguments[3]);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
Status = DiskIo->WriteDisk (
|
|
DiskIo,
|
|
(UINT32)Arguments[2],
|
|
(UINT64)PhysAddr,
|
|
Arguments[3],
|
|
(VOID *)Argument5
|
|
);
|
|
|
|
FreePool ((VOID *)Argument5);
|
|
|
|
break;
|
|
case SysCallUnicodeStriColl:
|
|
//
|
|
// Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This
|
|
// Argument 2: CHAR16 *Str1
|
|
// Argument 3: CHAR16 *Str2
|
|
//
|
|
Unicode = FindInterface (FALSE, (VOID *)Arguments[1]);
|
|
|
|
if (Unicode == NULL) {
|
|
Status = EFI_NOT_FOUND;
|
|
break;
|
|
}
|
|
|
|
if ((CHAR16 *)Arguments[2] != NULL) {
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + StrSize ((CHAR16 *)Arguments[2]) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[2]), (CHAR16 *)Arguments[2]);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
if ((VOID *)Argument4 == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((CHAR16 *)Arguments[3] != NULL) {
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + StrSize ((CHAR16 *)Arguments[3]) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[3]), (CHAR16 *)Arguments[3]);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
if ((VOID *)Argument5 == NULL) {
|
|
if ((VOID *)Argument4 != NULL) {
|
|
FreePool ((VOID *)Argument4);
|
|
}
|
|
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Status = (EFI_STATUS)Unicode->StriColl (
|
|
Unicode,
|
|
(CHAR16 *)Argument4,
|
|
(CHAR16 *)Argument5
|
|
);
|
|
|
|
if ((VOID *)Argument4 != NULL) {
|
|
FreePool ((VOID *)Argument4);
|
|
}
|
|
|
|
if ((VOID *)Argument5 != NULL) {
|
|
FreePool ((VOID *)Argument5);
|
|
}
|
|
|
|
break;
|
|
case SysCallUnicodeMetaiMatch:
|
|
//
|
|
// Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This
|
|
// Argument 2: CHAR16 *String
|
|
// Argument 3: CHAR16 *Pattern
|
|
//
|
|
Unicode = FindInterface (FALSE, (VOID *)Arguments[1]);
|
|
|
|
if (Unicode == NULL) {
|
|
Status = EFI_NOT_FOUND;
|
|
break;
|
|
}
|
|
|
|
if ((CHAR16 *)Arguments[2] != NULL) {
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + StrSize ((CHAR16 *)Arguments[2]) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[2]), (CHAR16 *)Arguments[2]);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
if ((VOID *)Argument4 == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((CHAR16 *)Arguments[3] != NULL) {
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + StrSize ((CHAR16 *)Arguments[3]) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[3]), (CHAR16 *)Arguments[3]);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
if ((VOID *)Argument5 == NULL) {
|
|
if ((VOID *)Argument4 != NULL) {
|
|
FreePool ((VOID *)Argument4);
|
|
}
|
|
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Status = (EFI_STATUS)Unicode->MetaiMatch (
|
|
Unicode,
|
|
(CHAR16 *)Argument4,
|
|
(CHAR16 *)Argument5
|
|
);
|
|
|
|
if ((VOID *)Argument4 != NULL) {
|
|
FreePool ((VOID *)Argument4);
|
|
}
|
|
|
|
if ((VOID *)Argument5 != NULL) {
|
|
FreePool ((VOID *)Argument5);
|
|
}
|
|
|
|
break;
|
|
case SysCallUnicodeStrLwr:
|
|
//
|
|
// Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This
|
|
// Argument 2: CHAR16 *Str
|
|
//
|
|
Unicode = FindInterface (FALSE, (VOID *)Arguments[1]);
|
|
|
|
if (Unicode == NULL) {
|
|
Status = EFI_NOT_FOUND;
|
|
break;
|
|
}
|
|
|
|
if ((CHAR16 *)Arguments[2] != NULL) {
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + StrSize ((CHAR16 *)Arguments[2]) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[2]), (CHAR16 *)Arguments[2]);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
if ((VOID *)Argument4 == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Unicode->StrLwr (
|
|
Unicode,
|
|
(CHAR16 *)Argument4
|
|
);
|
|
|
|
if ((VOID *)Argument4 != NULL) {
|
|
AllowSupervisorAccessToUserMemory ();
|
|
Status = StrCpyS ((CHAR16 *)Arguments[2], StrLen ((CHAR16 *)Arguments[2]) + 1, (CHAR16 *)Argument4);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
FreePool ((VOID *)Argument4);
|
|
}
|
|
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
case SysCallUnicodeStrUpr:
|
|
//
|
|
// Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This
|
|
// Argument 2: CHAR16 *Str
|
|
//
|
|
Unicode = FindInterface (FALSE, (VOID *)Arguments[1]);
|
|
|
|
if (Unicode == NULL) {
|
|
Status = EFI_NOT_FOUND;
|
|
break;
|
|
}
|
|
|
|
if ((CHAR16 *)Arguments[2] != NULL) {
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + StrSize ((CHAR16 *)Arguments[2]) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[2]), (CHAR16 *)Arguments[2]);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
if ((VOID *)Argument4 == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Unicode->StrUpr (
|
|
Unicode,
|
|
(CHAR16 *)Argument4
|
|
);
|
|
|
|
if ((VOID *)Argument4 != NULL) {
|
|
AllowSupervisorAccessToUserMemory ();
|
|
Status = StrCpyS ((CHAR16 *)Arguments[2], StrLen ((CHAR16 *)Arguments[2]) + 1, (CHAR16 *)Argument4);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
FreePool ((VOID *)Argument4);
|
|
}
|
|
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
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 *)Arguments[1]);
|
|
|
|
if (Unicode == NULL) {
|
|
Status = EFI_NOT_FOUND;
|
|
break;
|
|
}
|
|
|
|
if ((CHAR8 *)Arguments[3] != NULL) {
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + Arguments[2] - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
Argument4 = (UINTN)AllocateCopyPool (Arguments[2], (CHAR8 *)Arguments[3]);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
if ((VOID *)Argument4 == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((CHAR16 *)Arguments[4] != NULL) {
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + 2 * (Arguments[2] + 1) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
Argument5 = (UINTN)AllocatePool (2 * (Arguments[2] + 1));
|
|
if ((VOID *)Argument5 == NULL) {
|
|
if ((VOID *)Argument4 != NULL) {
|
|
FreePool ((VOID *)Argument4);
|
|
}
|
|
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Unicode->FatToStr (
|
|
Unicode,
|
|
Arguments[2],
|
|
(CHAR8 *)Argument4,
|
|
(CHAR16 *)Argument5
|
|
);
|
|
|
|
if ((VOID *)Argument4 != NULL) {
|
|
FreePool ((VOID *)Argument4);
|
|
}
|
|
|
|
if ((VOID *)Argument5 != NULL) {
|
|
AllowSupervisorAccessToUserMemory ();
|
|
CopyMem ((VOID *)Arguments[4], (VOID *)Argument5, 2 * (Arguments[2] + 1));
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
FreePool ((VOID *)Argument5);
|
|
}
|
|
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
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 *)Arguments[1]);
|
|
|
|
if (Unicode == NULL) {
|
|
Status = EFI_NOT_FOUND;
|
|
break;
|
|
}
|
|
|
|
if ((CHAR16 *)Arguments[2] != NULL) {
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
AllowSupervisorAccessToUserMemory ();
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + StrSize ((CHAR16 *)Arguments[2]) - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[2]), (CHAR16 *)Arguments[2]);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
if ((VOID *)Argument4 == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((CHAR8 *)Arguments[4] != NULL) {
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + Arguments[3] - 1), &Attributes);
|
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
|
|
|
Argument5 = (UINTN)AllocatePool (Arguments[3]);
|
|
if ((VOID *)Argument5 == NULL) {
|
|
if ((VOID *)Argument4 != NULL) {
|
|
FreePool ((VOID *)Argument4);
|
|
}
|
|
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Status = (EFI_STATUS)Unicode->StrToFat (
|
|
Unicode,
|
|
(CHAR16 *)Argument4,
|
|
Arguments[3],
|
|
(CHAR8 *)Argument5
|
|
);
|
|
|
|
if ((VOID *)Argument4 != NULL) {
|
|
FreePool ((VOID *)Argument4);
|
|
}
|
|
|
|
if ((VOID *)Argument5 != NULL) {
|
|
AllowSupervisorAccessToUserMemory ();
|
|
CopyMem ((VOID *)Arguments[4], (VOID *)Argument5, Arguments[3]);
|
|
ForbidSupervisorAccessToUserMemory ();
|
|
|
|
FreePool ((VOID *)Argument5);
|
|
}
|
|
|
|
break;
|
|
case SysCallGetUserPageTable:
|
|
//
|
|
// No Arguments
|
|
//
|
|
Status = (EFI_STATUS)gUserPageTable;
|
|
|
|
break;
|
|
default:
|
|
DEBUG ((DEBUG_ERROR, "Core: Unknown syscall type.\n"));
|
|
Status = EFI_UNSUPPORTED;
|
|
break;
|
|
}
|
|
|
|
FreePool (Arguments);
|
|
return Status;
|
|
}
|