0
0
mirror of https://github.com/edk2-porting/edk2-msm synced 2025-05-23 04:27:59 +00:00
Files
Xilin Wu 1cc6cfc41a Project refactor
🤯
2022-10-25 20:54:23 +08:00

145 lines
3.5 KiB
C
Executable File

#include <Uefi.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/MsPlatformDevicesLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/MemoryMapHelperLib.h>
#include <Library/BaseMemoryLib.h>
#include <Protocol/EFIScm.h>
#include <Protocol/scm_sip_interface.h>
#include <Library/RFSProtectionLib.h>
#define MAX_DESTINATION_VMS 3
EFI_STATUS
EFIAPI
RFSProtectSharedArea(UINT64 efsBaseAddr, UINT64 efsBaseSize)
{
EFI_STATUS Status = EFI_SUCCESS;
hyp_memprot_ipa_info_t ipaInfo;
QCOM_SCM_PROTOCOL *pQcomScmProtocol = NULL;
UINT32 dataSize = 0;
UINT32 sourceVM = AC_VM_HLOS;
UINT64 results[SCM_MAX_NUM_RESULTS] = {0};
VOID *data = NULL;
// Allow both HLOS (Windows) and MSS (Modem Subsystem) to access the shared memory region
// This is needed otherwise the Modem Subsystem will CRASH when attempting to read data
hyp_memprot_dstVM_perm_info_t dstVM_perm_info[MAX_DESTINATION_VMS] = {
{
AC_VM_HLOS,
(VM_PERM_R | VM_PERM_W),
(UINT64)NULL,
0
},
{
AC_VM_MSS_MSA,
(VM_PERM_R | VM_PERM_W),
(UINT64)NULL,
0
},
{
AC_VM_MSS_NAV,
(VM_PERM_R | VM_PERM_W),
(UINT64)NULL,
0
}
};
UINT64 parameterArray[SCM_MAX_NUM_PARAMETERS] = {0};
hyp_memprot_assign_t *assign = (hyp_memprot_assign_t *)parameterArray;
Status = gBS->LocateProtocol(
&gQcomScmProtocolGuid,
NULL,
(VOID **)&pQcomScmProtocol
);
if (EFI_ERROR(Status)) {
return Status;
}
// Fill in the address details
ipaInfo.IPAaddr = efsBaseAddr;
ipaInfo.IPAsize = efsBaseSize;
dataSize = sizeof(hyp_memprot_ipa_info_t) +
sizeof(sourceVM) +
(MAX_DESTINATION_VMS * sizeof(hyp_memprot_dstVM_perm_info_t)) +
4;
data = AllocateZeroPool(dataSize);
if (data == NULL) {
return EFI_OUT_OF_RESOURCES;
}
assign->IPAinfolist = (UINT64)data;
CopyMem(
(VOID *)assign->IPAinfolist,
&ipaInfo,
sizeof(hyp_memprot_ipa_info_t)
);
assign->IPAinfolistsize = sizeof(hyp_memprot_ipa_info_t);
assign->sourceVMlist =
(UINT64)data +
sizeof(hyp_memprot_ipa_info_t);
CopyMem(
(VOID *)assign->sourceVMlist,
&sourceVM,
sizeof(sourceVM)
);
assign->srcVMlistsize = sizeof(sourceVM);
assign->destVMlist =
(UINT64)data +
sizeof(hyp_memprot_ipa_info_t) +
sizeof(sourceVM) +
4;
CopyMem(
(VOID *)assign->destVMlist,
dstVM_perm_info,
MAX_DESTINATION_VMS * sizeof(hyp_memprot_dstVM_perm_info_t)
);
assign->destVMlistsize = MAX_DESTINATION_VMS * sizeof(hyp_memprot_dstVM_perm_info_t);
assign->spare = 0;
// Send the hypervisor call
Status = pQcomScmProtocol->ScmSipSysCall(
pQcomScmProtocol,
HYP_MEM_PROTECT_ASSIGN,
HYP_MEM_PROTECT_ASSIGN_PARAM_ID,
parameterArray,
results
);
return Status;
}
EFI_STATUS
EFIAPI
RFSLocateAndProtectSharedArea()
{
ARM_MEMORY_REGION_DESCRIPTOR_EX MpssEfs;
if (!EFI_ERROR(LocateMemoryMapAreaByName("MPSS_EFS", &MpssEfs))) {
return RFSProtectSharedArea(MpssEfs.Address, MpssEfs.Length);
}
return EFI_NOT_FOUND;
}