Ring3: Defined SysCallBootService() for ARM.

This commit is contained in:
Mikhail Krichanov 2024-07-09 11:40:26 +03:00
parent ae234e908f
commit bdea79e171
6 changed files with 90 additions and 50 deletions

View File

@ -9,6 +9,14 @@
#ifndef DEFAULT_EXCEPTION_HANDLER_LIB_H_
#define DEFAULT_EXCEPTION_HANDLER_LIB_H_
typedef
EFI_STATUS
(EFIAPI *EFI_SYS_CALL_BOOT_SERVICE)(
IN UINT8 Type,
IN VOID *CoreRbp,
IN VOID *UserRsp
);
/**
This is the default action to take on an unexpected exception
@ -26,7 +34,7 @@ DefaultExceptionHandler (
VOID
EFIAPI
InitializeSysCallHandler (
IN VOID *Handler
IN EFI_SYS_CALL_BOOT_SERVICE Handler
);
#endif // DEFAULT_EXCEPTION_HANDLER_LIB_H_

View File

@ -220,8 +220,12 @@ ASM_PFX(AsmCommonExceptionEntry):
cmp R3, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f))
cmpne R3, #0x10 @
stmdaeq R2, {lr}^ @ save unbanked lr
addeq R2, SP, #0x34 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.SP
stmdaeq R2, {sp}^ @ save unbanked sp
@ else
stmdane R2, {lr} @ save SVC lr
addne R1, SP, #0x60 @ We pushed 0x60 bytes on the stack
strne R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP
ldr R5, [SP, #0x58] @ PC is the LR pushed by srsfd
@ -230,6 +234,7 @@ ASM_PFX(AsmCommonExceptionEntry):
cmp r4, #1 @ // UND & SVC have different LR adjust for Thumb
bhi NoAdjustNeeded
ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack
tst r1, #0x20 @ if ((CPSR & T)) == T) { // Thumb Mode on entry
addne R5, R5, #2 @ PC += 2;
strne R5,[SP,#0x58] @ Update LR value pushed by srsfd
@ -238,9 +243,6 @@ NoAdjustNeeded:
str R5, [SP, #0x3c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC
add R1, SP, #0x60 @ We pushed 0x60 bytes on the stack
str R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP
@ R0 is ExceptionType
mov R1,SP @ R1 is SystemContext
@ -253,7 +255,7 @@ NoAdjustNeeded:
subne SP, SP, #4 @ Adjust SP if not 8-byte aligned
/*
VOID
EFI_STATUS
EFIAPI
CommonCExceptionHandler (
IN EFI_EXCEPTION_TYPE ExceptionType, R0
@ -261,6 +263,8 @@ CommonCExceptionHandler (
)
*/
mov R5, R0 @ R5 is ExceptionType
blx ASM_PFX(CommonCExceptionHandler) @ Call exception handler
mov SP, R4 @ Restore SP
@ -275,25 +279,14 @@ CommonCExceptionHandler (
ldr R1, [SP, #0x44] @ Restore EFI_SYSTEM_CONTEXT_ARM.DFSR
mcr p15, 0, R1, c5, c0, 0 @ Write DFSR
ldr R1,[SP,#0x3c] @ EFI_SYSTEM_CONTEXT_ARM.PC
str R1,[SP,#0x58] @ Store it back to srsfd stack slot so it can be restored
ldr R1,[SP,#0x40] @ EFI_SYSTEM_CONTEXT_ARM.CPSR
str R1,[SP,#0x5c] @ Store it back to srsfd stack slot so it can be restored
add R3, SP, #0x54 @ Make R3 point to SVC LR saved on entry
add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
and R1, R1, #0x1f @ Check to see if User or System Mode
cmp R1, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f))
cmpne R1, #0x10 @
ldmibeq R2, {lr}^ @ restore unbanked lr
cmp R5, #2 @ if (ExceptionType == SoftwareInterrupt)
addeq SP, SP, #0x4 @ Preserve EFI_STATUS return result in R0.
ldmfdeq SP!, {R1-R12} @
@ else
ldmibne R3, {lr} @ restore SVC lr, via ldmfd SP!, {LR}
ldmfdne SP!, {R0-R12} @ Restore general purpose registers
ldmfd SP!,{R0-R12} @ Restore general purpose registers
@ Exception handler can not change SP
add SP,SP,#0x20 @ Clear out the remaining stack space
ldmfd SP!,{LR} @ restore the link register for this context
rfefd SP! @ return from exception via srsfd stack slot

View File

@ -22,6 +22,7 @@
#include <Guid/DebugImageInfoTable.h>
#include <Protocol/DebugSupport.h>
#include <Protocol/LoadedImage.h>
#include <Library/DefaultExceptionHandlerLib.h>
//
// Maximum number of characters to print to serial (UINT8s) and to console if
@ -29,14 +30,6 @@
//
#define MAX_PRINT_CHARS 100
typedef
EFI_STATUS
(EFIAPI *EFI_SYS_CALL_BOOT_SERVICE)(
IN UINT8 Type,
IN VOID *CoreRbp,
IN VOID *UserRsp
);
STATIC CHAR8 *gExceptionTypeString[] = {
"Synchronous",
"IRQ",
@ -195,10 +188,10 @@ BaseName (
VOID
EFIAPI
InitializeSysCallHandler (
IN VOID *Handler
IN EFI_SYS_CALL_BOOT_SERVICE Handler
)
{
mSysCallHandler = (EFI_SYS_CALL_BOOT_SERVICE)Handler;
mSysCallHandler = Handler;
}
/**

View File

@ -39,6 +39,8 @@ typedef struct {
CHAR8 Char;
} CPSR_CHAR;
STATIC EFI_SYS_CALL_BOOT_SERVICE mSysCallHandler;
STATIC CONST CPSR_CHAR mCpsrChar[] = {
{ 31, 'n' },
{ 30, 'z' },
@ -187,6 +189,15 @@ STATIC CHAR8 *gExceptionTypeString[] = {
"FIQ"
};
VOID
EFIAPI
InitializeSysCallHandler (
IN EFI_SYS_CALL_BOOT_SERVICE Handler
)
{
mSysCallHandler = Handler;
}
/**
This is the default action to take on an unexpected exception
@ -212,6 +223,14 @@ DefaultExceptionHandler (
BOOLEAN DfsrWrite;
UINT32 PcAdjust;
if (ExceptionType == EXCEPT_ARM_SOFTWARE_INTERRUPT) {
return mSysCallHandler (
SystemContext.SystemContextArm->R0,
&(SystemContext.SystemContextArm->R1),
&(SystemContext.SystemContextArm->SP)
);
}
PcAdjust = 0;
CharCount = AsciiSPrint (

View File

@ -22,26 +22,6 @@
ASM_FUNC(CallInstallMultipleProtocolInterfaces)
bx LR
//------------------------------------------------------------------------------
// 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, ...
//------------------------------------------------------------------------------
ASM_FUNC(CoreBootServices)
bx LR
//------------------------------------------------------------------------------
// EFI_STATUS
// EFIAPI

View File

@ -6,6 +6,7 @@
**/
#include <Library/ArmLib.h>
#include <Library/DefaultExceptionHandlerLib.h>
#include "DxeMain.h"
@ -33,6 +34,50 @@ ArmClearPan (
VOID
);
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;
}
DisableSMAP ();
//
// First 3 arguments are passed through R1-R3 and copied to SysCall Stack.
//
CopyMem ((VOID *)((UINTN)Physical + sizeof (UINTN)), (VOID *)CoreRbp, 3 * sizeof (UINTN));
//
// All remaining arguments are on User Stack.
//
CopyMem ((VOID *)((UINTN)Physical + 4 * sizeof (UINTN)), (VOID *)UserRsp, 5 * 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 (
@ -49,6 +94,8 @@ InitializeMsr (
DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n"));
// ASSERT (FALSE);
}
InitializeSysCallHandler (SysCallBootService);
}
VOID