mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-21 20:54:29 +02:00
Ring3: Moved SysCall code to DxeCore.
This commit is contained in:
parent
b1d42c0979
commit
32e8bcbb62
@ -2823,4 +2823,23 @@ SetUefiImageMemoryAttributes (
|
||||
IN UINT64 Attributes
|
||||
);
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
CoreBootServices (
|
||||
IN UINT8 Type,
|
||||
IN UINTN FunctionAddress,
|
||||
...
|
||||
);
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
#endif
|
||||
|
@ -67,6 +67,10 @@
|
||||
Dispatcher/Dispatcher.c
|
||||
DxeMain/DxeProtocolNotify.c
|
||||
DxeMain/DxeMain.c
|
||||
SysCall/BootServices.c
|
||||
|
||||
[Sources.X64]
|
||||
SysCall/X64/CoreBootServices.nasm
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
|
@ -27,7 +27,7 @@ STATIC EFI_EVENT mPeCoffEmuProtocolRegistrationEvent;
|
||||
STATIC VOID *mPeCoffEmuProtocolNotifyRegistration;
|
||||
|
||||
extern BOOLEAN gBdsStarted;
|
||||
extern VOID *gCoreSysCallStackTop;
|
||||
VOID *gCoreSysCallStackTop;
|
||||
|
||||
//
|
||||
// This code is needed to build the Image handle for the DXE Core
|
||||
|
154
MdeModulePkg/Core/Dxe/SysCall/BootServices.c
Normal file
154
MdeModulePkg/Core/Dxe/SysCall/BootServices.c
Normal file
@ -0,0 +1,154 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2024, Mikhail Krichanov. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
**/
|
||||
|
||||
#include <Base.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
DisableSMAP (
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
EnableSMAP (
|
||||
VOID
|
||||
);
|
||||
|
||||
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 enum {
|
||||
SysCallReadMemory = 0,
|
||||
SysCallAllocateRing3Pages = 1,
|
||||
SysCallAllocateCoreCopy = 2,
|
||||
SysCallLocateProtocol = 3,
|
||||
SysCallOpenProtocol = 4,
|
||||
SysCallMax
|
||||
} SYS_CALL_TYPE;
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
CallBootService (
|
||||
IN UINT8 Type,
|
||||
IN VOID **FunctionAddress,
|
||||
IN UINTN CoreRbp,
|
||||
IN UINTN UserRsp
|
||||
)
|
||||
{
|
||||
UINTN Status;
|
||||
VOID *Pointer;
|
||||
VOID * Arg4;
|
||||
VOID * Arg5;
|
||||
UINT32 Arg6;
|
||||
EFI_ALLOCATE_RING3_PAGES Func1;
|
||||
EFI_ALLOCATE_CORE_COPY Func2;
|
||||
EFI_LOCATE_PROTOCOL Func3;
|
||||
EFI_OPEN_PROTOCOL Func4;
|
||||
// Stack:
|
||||
// rcx - Rip for SYSCALL
|
||||
// r8 - Argument 1
|
||||
// rbp - User Rbp
|
||||
// r9 - Argument 2
|
||||
// r11 - User data segment selector <- CoreRbp
|
||||
// rsp - User Rsp
|
||||
switch (Type) {
|
||||
case SysCallReadMemory:
|
||||
return *(UINTN *)FunctionAddress;
|
||||
|
||||
case SysCallAllocateRing3Pages:
|
||||
Func1 = (EFI_ALLOCATE_RING3_PAGES)*FunctionAddress;
|
||||
Status = Func1 (
|
||||
*((UINTN *)CoreRbp + 3),
|
||||
&Pointer
|
||||
);
|
||||
DisableSMAP ();
|
||||
*(UINTN *)(*((UINTN *)CoreRbp + 1)) = (UINTN)Pointer;
|
||||
EnableSMAP ();
|
||||
return (UINTN)Status;
|
||||
|
||||
case SysCallAllocateCoreCopy:
|
||||
DisableSMAP ();
|
||||
Func2 = (EFI_ALLOCATE_CORE_COPY)*FunctionAddress;
|
||||
Status = (UINTN)Func2 (
|
||||
*((UINTN *)CoreRbp + 3),
|
||||
(VOID *)*((UINTN *)CoreRbp + 1)
|
||||
);
|
||||
EnableSMAP ();
|
||||
return (UINTN)Status;
|
||||
|
||||
case SysCallLocateProtocol:
|
||||
Func3 = (EFI_LOCATE_PROTOCOL)*FunctionAddress;
|
||||
Status = Func3 (
|
||||
(VOID *)*((UINTN *)CoreRbp + 3),
|
||||
(VOID *)*((UINTN *)CoreRbp + 1),
|
||||
&Pointer
|
||||
);
|
||||
DisableSMAP ();
|
||||
*((UINTN *)UserRsp + 5) = (UINTN)Pointer;
|
||||
EnableSMAP ();
|
||||
return (UINTN)Status;
|
||||
|
||||
case SysCallOpenProtocol:
|
||||
DisableSMAP ();
|
||||
Arg4 = (VOID *)*((UINTN *)UserRsp + 6);
|
||||
Arg5 = (VOID *)*((UINTN *)UserRsp + 7);
|
||||
Arg6 = (UINT32)*((UINTN *)UserRsp + 8);
|
||||
EnableSMAP ();
|
||||
Func4 = (EFI_OPEN_PROTOCOL)*FunctionAddress;
|
||||
Status = Func4 (
|
||||
(VOID *)*((UINTN *)CoreRbp + 3),
|
||||
(VOID *)*((UINTN *)CoreRbp + 1),
|
||||
&Pointer,
|
||||
Arg4,
|
||||
Arg5,
|
||||
Arg6
|
||||
);
|
||||
DisableSMAP ();
|
||||
*((UINTN *)UserRsp + 5) = (UINTN)Pointer;
|
||||
EnableSMAP ();
|
||||
return (UINTN)Status;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
161
MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm
Normal file
161
MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm
Normal file
@ -0,0 +1,161 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (c) 2024, Mikhail Krichanov. All rights reserved.
|
||||
; SPDX-License-Identifier: BSD-3-Clause
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
DEFAULT REL
|
||||
SECTION .text
|
||||
|
||||
extern ASM_PFX(CallBootService)
|
||||
extern ASM_PFX(gCoreSysCallStackTop)
|
||||
|
||||
%macro CallSysRet 0
|
||||
; Prepare SYSRET arguments.
|
||||
mov rcx, [rbp + 8*4]
|
||||
pop rdx
|
||||
|
||||
; Switch from Core to User data segment selectors.
|
||||
pop r11
|
||||
|
||||
o16 mov ds, r11
|
||||
o16 mov es, r11
|
||||
o16 mov fs, r11
|
||||
o16 mov gs, r11
|
||||
|
||||
; Restore RFLAGS in R11 for SYSRET.
|
||||
pushfq
|
||||
pop r11
|
||||
|
||||
; Switch to User Stack.
|
||||
pop rbp
|
||||
pop rbp
|
||||
mov rsp, rdx
|
||||
|
||||
; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX.
|
||||
o64 sysret
|
||||
; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11.
|
||||
%endmacro
|
||||
|
||||
global ASM_PFX(DisableSMAP)
|
||||
ASM_PFX(DisableSMAP):
|
||||
pushfq
|
||||
pop r10
|
||||
or r10, 0x40000 ; Set AC (bit 18)
|
||||
push r10
|
||||
popfq
|
||||
ret
|
||||
|
||||
global ASM_PFX(EnableSMAP)
|
||||
ASM_PFX(EnableSMAP):
|
||||
pushfq
|
||||
pop r10
|
||||
and r10, ~0x40000 ; Clear AC (bit 18)
|
||||
push r10
|
||||
popfq
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; UINTN
|
||||
; EFIAPI
|
||||
; CoreBootServices (
|
||||
; IN UINT8 Type,
|
||||
; IN UINTN FunctionAddress,
|
||||
; ...
|
||||
; );
|
||||
;
|
||||
; (rcx) RIP of the next instruction saved by SYSCALL in SysCall().
|
||||
; (rdx) FunctionAddress.
|
||||
; (r8) Argument 1 of the called function.
|
||||
; (r9) Argument 2 of the called function.
|
||||
; (r10) Type.
|
||||
; (r11) RFLAGS saved by SYSCALL in SysCall().
|
||||
;On stack Argument 3, 4, ...
|
||||
;------------------------------------------------------------------------------
|
||||
global ASM_PFX(CoreBootServices)
|
||||
ASM_PFX(CoreBootServices):
|
||||
; Save User data segment selector temporarily in R11.
|
||||
mov r11, ds
|
||||
|
||||
; Switch from User to Core data segment selectors.
|
||||
mov ax, ss
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
; Save User Stack pointers and switch to Core SysCall Stack.
|
||||
mov rax, [ASM_PFX(gCoreSysCallStackTop)]
|
||||
; Save return address for SYSRET.
|
||||
sub rax, 8
|
||||
mov [rax], rcx
|
||||
mov rcx, r10
|
||||
sub rax, 8
|
||||
mov [rax], r8
|
||||
sub rax, 8
|
||||
mov [rax], rbp
|
||||
sub rax, 8
|
||||
mov [rax], r9
|
||||
; Save User data segment selector on Core SysCall Stack.
|
||||
sub rax, 8
|
||||
mov [rax], r11
|
||||
|
||||
mov r9, rsp
|
||||
|
||||
mov rsp, rax
|
||||
|
||||
mov rbp, rsp
|
||||
mov r8, rbp
|
||||
push r9
|
||||
|
||||
call ASM_PFX(CallBootService)
|
||||
|
||||
CallSysRet
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Routine Description:
|
||||
;
|
||||
; Routine for transfering control to user image with 2 parameters
|
||||
;
|
||||
; Arguments:
|
||||
;
|
||||
; (rcx) EntryPoint - Entry point with new stack.
|
||||
; (rdx) Context1 - Parameter1 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)
|
||||
ASM_PFX(InternalEnterUserImage):
|
||||
; Set Data selectors
|
||||
mov rax, [rsp + 8*6]
|
||||
or rax, 3H ; RPL = 3
|
||||
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
; Save Code selector
|
||||
mov r10, [rsp + 8*5]
|
||||
or r10, 3H ; RPL = 3
|
||||
|
||||
; Prepare stack before swithcing
|
||||
push rax ; ss
|
||||
push r9 ; rsp
|
||||
push r10 ; cs
|
||||
push rcx ; rip
|
||||
|
||||
; Save 2 parameters
|
||||
mov rcx, rdx
|
||||
mov rdx, r8
|
||||
|
||||
; Pass control to user image
|
||||
retfq
|
@ -5114,17 +5114,6 @@ SwitchStack (
|
||||
...
|
||||
);
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
Generates a breakpoint on the CPU.
|
||||
|
||||
@ -6596,14 +6585,6 @@ AsmReadEflags (
|
||||
VOID
|
||||
);
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
CoreBootServices (
|
||||
IN UINT8 Type,
|
||||
IN UINTN FunctionAddress,
|
||||
...
|
||||
);
|
||||
|
||||
/**
|
||||
Reads the current value of the Control Register 0 (CR0).
|
||||
|
||||
|
@ -332,71 +332,6 @@ InternalSwitchStack (
|
||||
IN VA_LIST Marker
|
||||
);
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
DisableSMAP (
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
EnableSMAP (
|
||||
VOID
|
||||
);
|
||||
|
||||
typedef enum {
|
||||
SysCallReadMemory = 0,
|
||||
SysCallAllocateRing3Pages = 1,
|
||||
SysCallAllocateCoreCopy = 2,
|
||||
SysCallLocateProtocol = 3,
|
||||
SysCallOpenProtocol = 4,
|
||||
SysCallMax
|
||||
} SYS_CALL_TYPE;
|
||||
|
||||
typedef
|
||||
UINTN
|
||||
(EFIAPI *EFI_ALLOCATE_RING3_PAGES)(
|
||||
IN UINTN Pages,
|
||||
IN OUT VOID **Memory
|
||||
);
|
||||
|
||||
typedef
|
||||
VOID *
|
||||
(EFIAPI *EFI_ALLOCATE_CORE_COPY)(
|
||||
IN UINTN AllocationSize,
|
||||
IN CONST VOID *Buffer
|
||||
);
|
||||
|
||||
typedef
|
||||
UINTN
|
||||
(EFIAPI *EFI_LOCATE_PROTOCOL)(
|
||||
IN VOID *Protocol,
|
||||
IN VOID *Registration OPTIONAL,
|
||||
OUT VOID **Interface
|
||||
);
|
||||
|
||||
typedef
|
||||
UINTN
|
||||
(EFIAPI *EFI_OPEN_PROTOCOL)(
|
||||
IN VOID * Handle,
|
||||
IN VOID *Protocol,
|
||||
OUT VOID **Interface OPTIONAL,
|
||||
IN VOID * AgentHandle,
|
||||
IN VOID * ControllerHandle,
|
||||
IN UINT32 Attributes
|
||||
);
|
||||
|
||||
/**
|
||||
Worker function that returns a bit field from Operand.
|
||||
|
||||
|
@ -68,113 +68,3 @@ SwitchStack (
|
||||
//
|
||||
ASSERT (FALSE);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
CallBootService (
|
||||
IN UINT8 Type,
|
||||
IN VOID **FunctionAddress,
|
||||
IN UINTN CoreRbp,
|
||||
IN UINTN UserRsp
|
||||
)
|
||||
{
|
||||
UINTN Status;
|
||||
VOID *Pointer;
|
||||
VOID * Arg4;
|
||||
VOID * Arg5;
|
||||
UINT32 Arg6;
|
||||
EFI_ALLOCATE_RING3_PAGES Func1;
|
||||
EFI_ALLOCATE_CORE_COPY Func2;
|
||||
EFI_LOCATE_PROTOCOL Func3;
|
||||
EFI_OPEN_PROTOCOL Func4;
|
||||
// Stack:
|
||||
// rcx - Rip for SYSCALL
|
||||
// r8 - Argument 1
|
||||
// rbp - User Rbp
|
||||
// r9 - Argument 2
|
||||
// r11 - User data segment selector <- CoreRbp
|
||||
// rsp - User Rsp
|
||||
switch (Type) {
|
||||
case SysCallReadMemory:
|
||||
return *(UINTN *)FunctionAddress;
|
||||
|
||||
case SysCallAllocateRing3Pages:
|
||||
Func1 = (EFI_ALLOCATE_RING3_PAGES)*FunctionAddress;
|
||||
Status = Func1 (
|
||||
*((UINTN *)CoreRbp + 3),
|
||||
&Pointer
|
||||
);
|
||||
DisableSMAP ();
|
||||
*(UINTN *)(*((UINTN *)CoreRbp + 1)) = (UINTN)Pointer;
|
||||
EnableSMAP ();
|
||||
return (UINTN)Status;
|
||||
|
||||
case SysCallAllocateCoreCopy:
|
||||
DisableSMAP ();
|
||||
Func2 = (EFI_ALLOCATE_CORE_COPY)*FunctionAddress;
|
||||
Status = (UINTN)Func2 (
|
||||
*((UINTN *)CoreRbp + 3),
|
||||
(VOID *)*((UINTN *)CoreRbp + 1)
|
||||
);
|
||||
EnableSMAP ();
|
||||
return (UINTN)Status;
|
||||
|
||||
case SysCallLocateProtocol:
|
||||
Func3 = (EFI_LOCATE_PROTOCOL)*FunctionAddress;
|
||||
Status = Func3 (
|
||||
(VOID *)*((UINTN *)CoreRbp + 3),
|
||||
(VOID *)*((UINTN *)CoreRbp + 1),
|
||||
&Pointer
|
||||
);
|
||||
DisableSMAP ();
|
||||
*((UINTN *)UserRsp + 5) = (UINTN)Pointer;
|
||||
EnableSMAP ();
|
||||
return (UINTN)Status;
|
||||
|
||||
case SysCallOpenProtocol:
|
||||
DisableSMAP ();
|
||||
Arg4 = (VOID *)*((UINTN *)UserRsp + 6);
|
||||
Arg5 = (VOID *)*((UINTN *)UserRsp + 7);
|
||||
Arg6 = (UINT32)*((UINTN *)UserRsp + 8);
|
||||
EnableSMAP ();
|
||||
Func4 = (EFI_OPEN_PROTOCOL)*FunctionAddress;
|
||||
Status = Func4 (
|
||||
(VOID *)*((UINTN *)CoreRbp + 3),
|
||||
(VOID *)*((UINTN *)CoreRbp + 1),
|
||||
&Pointer,
|
||||
Arg4,
|
||||
Arg5,
|
||||
Arg6
|
||||
);
|
||||
DisableSMAP ();
|
||||
*((UINTN *)UserRsp + 5) = (UINTN)Pointer;
|
||||
EnableSMAP ();
|
||||
return (UINTN)Status;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
;------------------------------------------------------------------------------
|
||||
; Copyright (c) 2024, Mikhail Krichanov. All rights reserved.
|
||||
; SPDX-License-Identifier: BSD-3-Clause
|
||||
;
|
||||
; Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
|
||||
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
@ -16,8 +14,6 @@
|
||||
DEFAULT REL
|
||||
SECTION .text
|
||||
|
||||
extern ASM_PFX(CallBootService)
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Routine Description:
|
||||
;
|
||||
@ -46,158 +42,3 @@ ASM_PFX(InternalSwitchStack):
|
||||
;
|
||||
lea rsp, [r9 - 0x20]
|
||||
call rax
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Routine Description:
|
||||
;
|
||||
; Routine for transfering control to user image with 2 parameters
|
||||
;
|
||||
; Arguments:
|
||||
;
|
||||
; (rcx) EntryPoint - Entry point with new stack.
|
||||
; (rdx) Context1 - Parameter1 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)
|
||||
ASM_PFX(InternalEnterUserImage):
|
||||
; Set Data selectors
|
||||
mov rax, [rsp + 8*6]
|
||||
or rax, 3H ; RPL = 3
|
||||
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
; Save Code selector
|
||||
mov r10, [rsp + 8*5]
|
||||
or r10, 3H ; RPL = 3
|
||||
|
||||
; Prepare stack before swithcing
|
||||
push rax ; ss
|
||||
push r9 ; rsp
|
||||
push r10 ; cs
|
||||
push rcx ; rip
|
||||
|
||||
; Save 2 parameters
|
||||
mov rcx, rdx
|
||||
mov rdx, r8
|
||||
|
||||
; Pass control to user image
|
||||
retfq
|
||||
|
||||
%macro CallSysRet 0
|
||||
; Prepare SYSRET arguments.
|
||||
mov rcx, [rbp + 8*4]
|
||||
pop rdx
|
||||
|
||||
; Switch from Core to User data segment selectors.
|
||||
pop r11
|
||||
|
||||
o16 mov ds, r11
|
||||
o16 mov es, r11
|
||||
o16 mov fs, r11
|
||||
o16 mov gs, r11
|
||||
|
||||
; Restore RFLAGS in R11 for SYSRET.
|
||||
pushfq
|
||||
pop r11
|
||||
|
||||
; Switch to User Stack.
|
||||
pop rbp
|
||||
pop rbp
|
||||
mov rsp, rdx
|
||||
|
||||
; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX.
|
||||
o64 sysret
|
||||
; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11.
|
||||
%endmacro
|
||||
|
||||
global ASM_PFX(DisableSMAP)
|
||||
ASM_PFX(DisableSMAP):
|
||||
pushfq
|
||||
pop r10
|
||||
or r10, 0x40000 ; Set AC (bit 18)
|
||||
push r10
|
||||
popfq
|
||||
ret
|
||||
|
||||
global ASM_PFX(EnableSMAP)
|
||||
ASM_PFX(EnableSMAP):
|
||||
pushfq
|
||||
pop r10
|
||||
and r10, ~0x40000 ; Clear AC (bit 18)
|
||||
push r10
|
||||
popfq
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; UINTN
|
||||
; EFIAPI
|
||||
; CoreBootServices (
|
||||
; IN UINT8 Type,
|
||||
; IN UINTN FunctionAddress,
|
||||
; ...
|
||||
; );
|
||||
;
|
||||
; (rcx) RIP of the next instruction saved by SYSCALL in SysCall().
|
||||
; (rdx) FunctionAddress.
|
||||
; (r8) Argument 1 of the called function.
|
||||
; (r9) Argument 2 of the called function.
|
||||
; (r10) Type.
|
||||
; (r11) RFLAGS saved by SYSCALL in SysCall().
|
||||
;On stack Argument 3, 4, ...
|
||||
;------------------------------------------------------------------------------
|
||||
global ASM_PFX(CoreBootServices)
|
||||
ASM_PFX(CoreBootServices):
|
||||
; Save User data segment selector temporarily in R11.
|
||||
mov r11, ds
|
||||
|
||||
; Switch from User to Core data segment selectors.
|
||||
mov ax, ss
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
; Save User Stack pointers and switch to Core SysCall Stack.
|
||||
mov rax, [ASM_PFX(gCoreSysCallStackTop)]
|
||||
; Save return address for SYSRET.
|
||||
sub rax, 8
|
||||
mov [rax], rcx
|
||||
mov rcx, r10
|
||||
sub rax, 8
|
||||
mov [rax], r8
|
||||
sub rax, 8
|
||||
mov [rax], rbp
|
||||
sub rax, 8
|
||||
mov [rax], r9
|
||||
; Save User data segment selector on Core SysCall Stack.
|
||||
sub rax, 8
|
||||
mov [rax], r11
|
||||
|
||||
mov r9, rsp
|
||||
|
||||
mov rsp, rax
|
||||
|
||||
mov rbp, rsp
|
||||
mov r8, rbp
|
||||
push r9
|
||||
|
||||
call ASM_PFX(CallBootService)
|
||||
|
||||
CallSysRet
|
||||
|
||||
SECTION .data
|
||||
|
||||
global ASM_PFX(gCoreSysCallStackTop)
|
||||
ASM_PFX(gCoreSysCallStackTop):
|
||||
resq 1
|
||||
|
Loading…
x
Reference in New Issue
Block a user