mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-27 23:54:02 +02:00
Ring3: Refactored EnterUserImage() into CallRing3().
This commit is contained in:
parent
1b37dd79f6
commit
8a16ce73a7
@ -2845,15 +2845,11 @@ CoreBootServices (
|
|||||||
...
|
...
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
EnterUserImage (
|
CallRing3 (
|
||||||
IN SWITCH_STACK_ENTRY_POINT EntryPoint,
|
IN VOID *EntryPoint,
|
||||||
IN VOID *Context1 OPTIONAL,
|
...
|
||||||
IN VOID *Context2 OPTIONAL,
|
|
||||||
IN VOID *NewStack,
|
|
||||||
IN UINT16 CodeSelector,
|
|
||||||
IN UINT16 DataSelector
|
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1788,15 +1788,11 @@ CoreStartImage (
|
|||||||
Msr = (UINT64)(UINTN)CoreBootServices;
|
Msr = (UINT64)(UINTN)CoreBootServices;
|
||||||
AsmWriteMsr64 (MSR_IA32_LSTAR, Msr);
|
AsmWriteMsr64 (MSR_IA32_LSTAR, Msr);
|
||||||
|
|
||||||
EnterUserImage (
|
Image->Status = CallRing3 (
|
||||||
(SWITCH_STACK_ENTRY_POINT)(UINTN)Image->EntryPoint,
|
(VOID *)Image->EntryPoint,
|
||||||
ImageHandle,
|
ImageHandle,
|
||||||
Image->Info.SystemTable,
|
Image->Info.SystemTable
|
||||||
gRing3CallStackTop,
|
);
|
||||||
(UINT16)RING3_CODE64_SEL,
|
|
||||||
(UINT16)RING3_DATA64_SEL
|
|
||||||
);
|
|
||||||
Image->Status = EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -32,17 +32,6 @@ CallInstallMultipleProtocolInterfaces (
|
|||||||
IN VOID *Function
|
IN VOID *Function
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
InternalEnterUserImage (
|
|
||||||
IN SWITCH_STACK_ENTRY_POINT EntryPoint,
|
|
||||||
IN VOID *Context1 OPTIONAL,
|
|
||||||
IN VOID *Context2 OPTIONAL,
|
|
||||||
IN VOID *NewStack,
|
|
||||||
IN UINT16 CodeSelector,
|
|
||||||
IN UINT16 DataSelector
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINTN Argument1;
|
UINTN Argument1;
|
||||||
UINTN Argument2;
|
UINTN Argument2;
|
||||||
@ -85,7 +74,9 @@ CallBootService (
|
|||||||
EFI_HANDLE CoreHandle;
|
EFI_HANDLE CoreHandle;
|
||||||
|
|
||||||
EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding;
|
EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding;
|
||||||
|
//
|
||||||
|
// TODO: Check User variables.
|
||||||
|
//
|
||||||
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp, &Attributes);
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp, &Attributes);
|
||||||
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
||||||
|
|
||||||
@ -230,25 +221,3 @@ CallBootService (
|
|||||||
|
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
EnterUserImage (
|
|
||||||
IN SWITCH_STACK_ENTRY_POINT EntryPoint,
|
|
||||||
IN VOID *Context1 OPTIONAL,
|
|
||||||
IN VOID *Context2 OPTIONAL,
|
|
||||||
IN VOID *NewStack,
|
|
||||||
IN UINT16 CodeSelector,
|
|
||||||
IN UINT16 DataSelector
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ASSERT (EntryPoint != NULL);
|
|
||||||
ASSERT (NewStack != NULL);
|
|
||||||
|
|
||||||
//
|
|
||||||
// New stack must be aligned with CPU_STACK_ALIGNMENT
|
|
||||||
//
|
|
||||||
ASSERT (((UINTN)NewStack & (CPU_STACK_ALIGNMENT - 1)) == 0);
|
|
||||||
|
|
||||||
InternalEnterUserImage (EntryPoint, Context1, Context2, NewStack, CodeSelector, DataSelector);
|
|
||||||
}
|
|
||||||
|
@ -18,16 +18,6 @@ typedef enum {
|
|||||||
UserCallMax
|
UserCallMax
|
||||||
} USER_CALL_TYPE;
|
} USER_CALL_TYPE;
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
CallRing3 (
|
|
||||||
IN UINT8 Type,
|
|
||||||
IN UINT16 CodeSelector,
|
|
||||||
IN UINT16 DataSelector,
|
|
||||||
IN VOID *FunctionAddress,
|
|
||||||
...
|
|
||||||
);
|
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
CoreDriverBindingSupported (
|
CoreDriverBindingSupported (
|
||||||
@ -37,9 +27,6 @@ CoreDriverBindingSupported (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
return CallRing3 (
|
return CallRing3 (
|
||||||
UserDriverBindingSupported,
|
|
||||||
(UINT16)RING3_CODE64_SEL,
|
|
||||||
(UINT16)RING3_DATA64_SEL,
|
|
||||||
(VOID *)mUserDriverBindingSupported,
|
(VOID *)mUserDriverBindingSupported,
|
||||||
This,
|
This,
|
||||||
ControllerHandle,
|
ControllerHandle,
|
||||||
@ -56,9 +43,6 @@ CoreDriverBindingStart (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
return CallRing3 (
|
return CallRing3 (
|
||||||
UserDriverBindingStart,
|
|
||||||
(UINT16)RING3_CODE64_SEL,
|
|
||||||
(UINT16)RING3_DATA64_SEL,
|
|
||||||
(VOID *)mUserDriverBindingStart,
|
(VOID *)mUserDriverBindingStart,
|
||||||
This,
|
This,
|
||||||
ControllerHandle,
|
ControllerHandle,
|
||||||
@ -76,9 +60,6 @@ CoreDriverBindingStop (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
return CallRing3 (
|
return CallRing3 (
|
||||||
UserDriverBindingStop,
|
|
||||||
(UINT16)RING3_CODE64_SEL,
|
|
||||||
(UINT16)RING3_DATA64_SEL,
|
|
||||||
(VOID *)mUserDriverBindingStop,
|
(VOID *)mUserDriverBindingStop,
|
||||||
This,
|
This,
|
||||||
ControllerHandle,
|
ControllerHandle,
|
||||||
|
@ -5,14 +5,18 @@
|
|||||||
;
|
;
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
|
|
||||||
DEFAULT REL
|
#include <Register/Intel/ArchitecturalMsr.h>
|
||||||
SECTION .text
|
|
||||||
|
|
||||||
extern ASM_PFX(CallBootService)
|
extern ASM_PFX(CallBootService)
|
||||||
extern ASM_PFX(gCoreSysCallStackTop)
|
extern ASM_PFX(gCoreSysCallStackTop)
|
||||||
extern ASM_PFX(gRing3CallStackTop)
|
extern ASM_PFX(gRing3CallStackTop)
|
||||||
extern ASM_PFX(gRing3EntryPoint)
|
extern ASM_PFX(gRing3EntryPoint)
|
||||||
|
|
||||||
|
extern ASM_PFX(AsmReadMsr64)
|
||||||
|
|
||||||
|
DEFAULT REL
|
||||||
|
SECTION .text
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
; VOID
|
; VOID
|
||||||
; EFIAPI
|
; EFIAPI
|
||||||
@ -167,92 +171,69 @@ o64 sysret
|
|||||||
; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11.
|
; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11.
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
; Routine Description:
|
; EFI_STATUS
|
||||||
|
; EFIAPI
|
||||||
|
; CallRing3 (
|
||||||
|
; IN VOID *EntryPoint,
|
||||||
|
; ...
|
||||||
|
; );
|
||||||
;
|
;
|
||||||
; Routine for transfering control to user image with 2 parameters
|
; (rcx) EntryPoint - Entry point in User address space.
|
||||||
;
|
|
||||||
; Arguments:
|
|
||||||
;
|
|
||||||
; (rcx) EntryPoint - Entry point with new stack.
|
|
||||||
; (rdx) Context1 - Parameter1 for entry point.
|
; (rdx) Context1 - Parameter1 for entry point.
|
||||||
; (r8) Context2 - Parameter2 for entry point.
|
; (r8) Context2 - Parameter2 for entry point.
|
||||||
; (r9) NewStack - The pointer to new stack.
|
|
||||||
;On stack CodeSelector - Segment selector for code.
|
|
||||||
;On stack DataSelector - Segment selector for data.
|
|
||||||
;
|
|
||||||
; Returns:
|
|
||||||
;
|
|
||||||
; None
|
|
||||||
;
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
global ASM_PFX(InternalEnterUserImage)
|
global ASM_PFX(CallRing3)
|
||||||
ASM_PFX(InternalEnterUserImage):
|
ASM_PFX(CallRing3):
|
||||||
; Set Data selectors
|
; Save input Arguments.
|
||||||
mov rax, [rsp + 8*6]
|
push r12
|
||||||
or rax, 3H ; RPL = 3
|
push r13
|
||||||
|
push r14
|
||||||
|
mov r12, rcx
|
||||||
|
mov r13, rdx
|
||||||
|
mov r14, r8
|
||||||
|
|
||||||
|
; Extract User Data selector.
|
||||||
|
mov rcx, MSR_IA32_STAR
|
||||||
|
call ASM_PFX(AsmReadMsr64)
|
||||||
|
; rax = ((RING3_CODE64_SEL - 16) << 16 | RING0_CODE64_SEL) << 32
|
||||||
|
shr rax, 48
|
||||||
|
add rax, 8
|
||||||
|
|
||||||
|
; Set Data selectors
|
||||||
|
or rax, 3H ; RPL = 3
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
|
|
||||||
; Save Code selector
|
; Prepare SYSRET arguments.
|
||||||
mov r10, [rsp + 8*5]
|
mov rcx, [gRing3EntryPoint]
|
||||||
or r10, 3H ; RPL = 3
|
mov rdx, r12
|
||||||
|
mov r8, r13
|
||||||
|
mov r9, r14
|
||||||
|
pushfq
|
||||||
|
pop r11
|
||||||
|
|
||||||
; Prepare stack before swithcing
|
; Restore stack and registers.
|
||||||
push rax ; ss
|
pop r14
|
||||||
push r9 ; rsp
|
pop r13
|
||||||
push r10 ; cs
|
pop r12
|
||||||
push rcx ; rip
|
|
||||||
|
|
||||||
; Save 2 parameters
|
; Save Core Stack pointers and switch to User Stack.
|
||||||
mov rcx, rdx
|
mov [ASM_PFX(CoreRsp)], rsp
|
||||||
mov rdx, r8
|
mov [ASM_PFX(CoreRbp)], rbp
|
||||||
|
mov rsp, [ASM_PFX(gRing3CallStackTop)]
|
||||||
|
mov rbp, rsp
|
||||||
|
|
||||||
; Pass control to user image
|
; Pass control to user image
|
||||||
retfq
|
o64 sysret
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
|
||||||
; EFI_STATUS
|
|
||||||
; EFIAPI
|
|
||||||
; CallRing3 (
|
|
||||||
; IN UINT8 Type,
|
|
||||||
; IN UINT16 CodeSelector,
|
|
||||||
; IN UINT16 DataSelector,
|
|
||||||
; IN VOID *FunctionAddress,
|
|
||||||
; ...
|
|
||||||
; );
|
|
||||||
;
|
|
||||||
; (rcx) Type.
|
|
||||||
; (rdx) CodeSelector - Segment selector for code.
|
|
||||||
; (r8) DataSelector - Segment selector for data.
|
|
||||||
; (r9) FunctionAddress
|
|
||||||
;
|
|
||||||
; (On User Stack) Argument 1, 2, 3, ...
|
|
||||||
;------------------------------------------------------------------------------
|
|
||||||
global ASM_PFX(CallRing3)
|
|
||||||
ASM_PFX(CallRing3):
|
|
||||||
; Set Data selectors
|
|
||||||
or r8, 3H ; RPL = 3
|
|
||||||
|
|
||||||
o16 mov ds, r8
|
|
||||||
o16 mov es, r8
|
|
||||||
o16 mov fs, r8
|
|
||||||
o16 mov gs, r8
|
|
||||||
|
|
||||||
; Save Code selector
|
|
||||||
or rdx, 3H ; RPL = 3
|
|
||||||
|
|
||||||
; Prepare stack before swithcing
|
|
||||||
push r8 ; ss
|
|
||||||
push qword [gRing3CallStackTop] ; rsp
|
|
||||||
push rdx ; cs
|
|
||||||
push qword [gRing3EntryPoint] ; rip
|
|
||||||
|
|
||||||
; Copy Arguments from Core Stack to User Stack + return address
|
|
||||||
|
|
||||||
; Pass control to User driver function.
|
|
||||||
retfq
|
|
||||||
coreReturnAddress:
|
coreReturnAddress:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
SECTION .data
|
||||||
|
ASM_PFX(CoreRsp):
|
||||||
|
resq 1
|
||||||
|
|
||||||
|
ASM_PFX(CoreRbp):
|
||||||
|
resq 1
|
||||||
|
@ -15,7 +15,18 @@ SECTION .text
|
|||||||
; IN EFI_HANDLE ImageHandle,
|
; IN EFI_HANDLE ImageHandle,
|
||||||
; IN EFI_SYSTEM_TABLE *SystemTable
|
; IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
; )
|
; )
|
||||||
|
;
|
||||||
|
; (rcx) _ModuleEntryPoint - Used by SYSRET.
|
||||||
|
; (rdx) EntryPoint - Function address in User address space.
|
||||||
|
; (r8) Context1 - Parameter1 for entry point.
|
||||||
|
; (r9) Context2 - Parameter2 for entry point.
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
global ASM_PFX(_ModuleEntryPoint)
|
global ASM_PFX(_ModuleEntryPoint)
|
||||||
ASM_PFX(_ModuleEntryPoint):
|
ASM_PFX(_ModuleEntryPoint):
|
||||||
ret
|
mov rcx, r8
|
||||||
|
mov r8, rdx
|
||||||
|
mov rdx, r9
|
||||||
|
|
||||||
|
call r8
|
||||||
|
|
||||||
|
ret
|
||||||
|
Loading…
x
Reference in New Issue
Block a user