audk/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c
2025-04-14 13:05:02 +03:00

171 lines
3.4 KiB
C

/** @file
Copyright (c) 2024, Mikhail Krichanov. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
**/
#include <Chipset/AArch64.h>
#include <Library/ArmLib.h>
#include <Library/ArmMmuLib.h>
#include <Library/DefaultExceptionHandlerLib.h>
#include "DxeMain.h"
STATIC UINTN mCoreSp;
UINTN gUserPageTable;
EFI_STATUS
EFIAPI
ArmCallRing3 (
IN RING3_CALL_DATA *Data,
IN VOID *StackPointer,
IN VOID *EntryPoint,
IN VOID *SysCallStack,
IN VOID *CoreStack,
IN UINTN UserPageTable
);
VOID
EFIAPI
ArmReturnToCore (
IN EFI_STATUS Status,
IN UINTN CoreSp
);
VOID
EFIAPI
ReturnToCore (
IN EFI_STATUS Status
)
{
ArmReturnToCore (Status, mCoreSp);
}
STATIC
EFI_STATUS
EFIAPI
SysCallBootService (
IN UINT8 Type,
IN VOID *CoreRbp,
IN VOID *UserRsp
)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS Physical;
Status = CoreAllocatePages (
AllocateAnyPages,
EfiRing3MemoryType,
EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)),
&Physical
);
if (EFI_ERROR (Status)) {
return Status;
}
AllowSupervisorAccessToUserMemory ();
CopyMem ((VOID *)((UINTN)Physical + sizeof (UINTN)), (VOID *)UserRsp, 8 * sizeof (UINTN));
ForbidSupervisorAccessToUserMemory ();
Status = CallBootService (
Type,
(CORE_STACK *)CoreRbp,
(RING3_STACK *)(UINTN)Physical
);
CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)));
return Status;
}
VOID
EFIAPI
MakeUserPageTableTemplate (
OUT UINTN *UserPageTableTemplate,
OUT UINTN *UserPageTableTemplateSize
)
{
ARM_MEMORY_REGION_DESCRIPTOR Descriptor;
VOID *MemorySizeHob;
MemorySizeHob = GetFirstGuidHob (&gArmVirtSystemMemorySizeGuid);
ASSERT (MemorySizeHob != NULL);
if (MemorySizeHob == NULL) {
return;
}
Descriptor.PhysicalBase = PcdGet64 (PcdSystemMemoryBase);
Descriptor.VirtualBase = Descriptor.PhysicalBase;
Descriptor.Length = *(UINT64 *)GET_GUID_HOB_DATA (MemorySizeHob);
Descriptor.Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK;
ArmMakeUserPageTableTemplate (
&Descriptor,
UserPageTableTemplate,
UserPageTableTemplateSize
);
}
VOID
EFIAPI
InitializeMsr (
IN OUT EFI_CONFIGURATION_TABLE *Table,
IN UINTN NumberOfEntries
)
{
UINTN Tcr;
UINTN Sctlr;
//
// Disable Hierarchical permissions just in case.
//
Tcr = ArmGetTCR ();
Tcr |= TCR_EL1_HPD0_MASK | TCR_EL1_HPD1_MASK;
ArmSetTCR (Tcr);
if (ArmHasPan ()) {
//
// Enable Privileged Access Never feature.
//
Sctlr = ArmReadSctlr ();
Sctlr |= SCTLR_EPAN;
ArmWriteSctlr (Sctlr);
ArmSetPan ();
}
InitializeSysCallHandler ((VOID *)SysCallBootService);
SetExceptionAddresses (NULL, 0);
}
VOID
EFIAPI
AllowSupervisorAccessToUserMemory (
VOID
)
{
if (ArmHasPan ()) {
ArmClearPan ();
}
}
VOID
EFIAPI
ForbidSupervisorAccessToUserMemory (
VOID
)
{
if (ArmHasPan ()) {
ArmSetPan ();
}
}
EFI_STATUS
EFIAPI
CallRing3 (
IN RING3_CALL_DATA *Data
)
{
return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp, gUserPageTable);
}