mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-27 23:54:02 +02:00
Ring3: Added helper function AllocateCoreCopy(), refactored SysCall.
This commit is contained in:
parent
e170598395
commit
12cc1a9a5d
@ -90,7 +90,8 @@ EFI_BOOT_SERVICES mBootServices = {
|
|||||||
(EFI_COPY_MEM)CopyMem, // CopyMem
|
(EFI_COPY_MEM)CopyMem, // CopyMem
|
||||||
(EFI_SET_MEM)SetMem, // SetMem
|
(EFI_SET_MEM)SetMem, // SetMem
|
||||||
(EFI_CREATE_EVENT_EX)CoreCreateEventEx, // CreateEventEx
|
(EFI_CREATE_EVENT_EX)CoreCreateEventEx, // CreateEventEx
|
||||||
(EFI_ALLOCATE_RING3_PAGES)AllocateRing3Pages
|
(EFI_ALLOCATE_RING3_PAGES)AllocateRing3Pages,
|
||||||
|
(EFI_ALLOCATE_CORE_COPY)AllocateCopyPool
|
||||||
};
|
};
|
||||||
|
|
||||||
EFI_DXE_SERVICES mDxeServices = {
|
EFI_DXE_SERVICES mDxeServices = {
|
||||||
|
@ -6699,6 +6699,7 @@ AsmReadEflags (
|
|||||||
UINTN
|
UINTN
|
||||||
EFIAPI
|
EFIAPI
|
||||||
CoreBootServices (
|
CoreBootServices (
|
||||||
|
IN UINT8 Type,
|
||||||
IN UINTN FunctionAddress,
|
IN UINTN FunctionAddress,
|
||||||
...
|
...
|
||||||
);
|
);
|
||||||
|
@ -229,6 +229,13 @@ EFI_STATUS
|
|||||||
IN OUT VOID **Memory
|
IN OUT VOID **Memory
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typedef
|
||||||
|
VOID *
|
||||||
|
(EFIAPI *EFI_ALLOCATE_CORE_COPY)(
|
||||||
|
IN UINTN AllocationSize,
|
||||||
|
IN CONST VOID *Buffer
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Frees memory pages.
|
Frees memory pages.
|
||||||
|
|
||||||
@ -2031,6 +2038,7 @@ typedef struct {
|
|||||||
EFI_SET_MEM SetMem;
|
EFI_SET_MEM SetMem;
|
||||||
EFI_CREATE_EVENT_EX CreateEventEx;
|
EFI_CREATE_EVENT_EX CreateEventEx;
|
||||||
EFI_ALLOCATE_RING3_PAGES AllocateRing3Pages;
|
EFI_ALLOCATE_RING3_PAGES AllocateRing3Pages;
|
||||||
|
EFI_ALLOCATE_CORE_COPY AllocateCoreCopy;
|
||||||
} EFI_BOOT_SERVICES;
|
} EFI_BOOT_SERVICES;
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -93,22 +93,27 @@ ASM_PFX(InternalEnterUserImage):
|
|||||||
retfq
|
retfq
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
; UINTN
|
; typedef enum {
|
||||||
; EFIAPI
|
; SysCallReadMemory = 0,
|
||||||
; CoreBootServices (
|
; SysCallAllocateRing3Pages = 1,
|
||||||
; IN UINTN FunctionAddress,
|
; SysCallAllocateCoreCopy = 2,
|
||||||
; ...
|
; SysCallLocateProtocol = 3,
|
||||||
; );
|
; SysCallMax
|
||||||
;
|
; } SYS_CALL_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) FunctionAddress.
|
|
||||||
; (r11) RFLAGS saved by SYSCALL in SysCall().
|
|
||||||
;On stack Argument 4, 5, ...
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
%define READ_MEMORY 0
|
||||||
|
%define ALLOCATE_RING3_PAGES 1
|
||||||
|
%define ALLOCATE_CORE_COPY 2
|
||||||
|
%define LOCATE_PROTOCOL 3
|
||||||
|
|
||||||
%macro CallSysRet 0
|
%macro CallSysRet 0
|
||||||
|
; Prepare SYSRET arguments.
|
||||||
|
pop rcx
|
||||||
|
|
||||||
|
; Switch from Core to User data segment selectors.
|
||||||
|
pop r11
|
||||||
|
|
||||||
o16 mov ds, r11
|
o16 mov ds, r11
|
||||||
o16 mov es, r11
|
o16 mov es, r11
|
||||||
o16 mov fs, r11
|
o16 mov fs, r11
|
||||||
@ -128,11 +133,45 @@ 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.
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
|
%macro DisableSMAP 0
|
||||||
|
pushfq
|
||||||
|
pop rcx
|
||||||
|
or rcx, 0x40000 ; Set AC (bit 18)
|
||||||
|
push rcx
|
||||||
|
popfq
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro EnableSMAP 0
|
||||||
|
pushfq
|
||||||
|
pop rcx
|
||||||
|
and rcx, ~0x40000 ; Clear AC (bit 18)
|
||||||
|
push rcx
|
||||||
|
popfq
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
; 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)
|
global ASM_PFX(CoreBootServices)
|
||||||
ASM_PFX(CoreBootServices):
|
ASM_PFX(CoreBootServices):
|
||||||
; Save User data segment selector.
|
; Save User data segment selector temporarily in R11.
|
||||||
mov r11, ds
|
mov r11, ds
|
||||||
|
|
||||||
|
; Switch from User to Core data segment selectors.
|
||||||
mov ax, ss
|
mov ax, ss
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
@ -148,34 +187,115 @@ ASM_PFX(CoreBootServices):
|
|||||||
push rbp
|
push rbp
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
|
|
||||||
cmp r10, 0
|
; Save User data segment selector on Core SysCall Stack.
|
||||||
je readMemory
|
push r11
|
||||||
|
|
||||||
|
; Save FunctionAddress in R11 as it will be called later.
|
||||||
|
mov r11, rdx
|
||||||
|
|
||||||
; Save return address for SYSRET.
|
; Save return address for SYSRET.
|
||||||
push rcx
|
push rcx
|
||||||
|
|
||||||
; Replace argument according to UEFI calling convention.
|
cmp r10, READ_MEMORY
|
||||||
mov rcx, rdx
|
je readMemory
|
||||||
mov rdx, r8
|
|
||||||
mov r8, r9
|
|
||||||
; mov r9, [rax + 8*3]
|
|
||||||
; mov r11, [rax + 8*4]
|
|
||||||
; push r11
|
|
||||||
; ...
|
|
||||||
|
|
||||||
; Call Boot Service by FunctionAddress.
|
cmp r10, ALLOCATE_RING3_PAGES
|
||||||
call [r10]
|
je allocateRing3Pages
|
||||||
|
|
||||||
; Prepare SYSRET arguments.
|
cmp r10, ALLOCATE_CORE_COPY
|
||||||
pop rcx
|
je allocateCoreCopy
|
||||||
|
|
||||||
CallSysRet
|
cmp r10, LOCATE_PROTOCOL
|
||||||
|
je locateProtocol
|
||||||
|
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
; UINTN
|
||||||
|
; ReadMemory (
|
||||||
|
; IN UINTN Address
|
||||||
|
; );
|
||||||
readMemory:
|
readMemory:
|
||||||
mov rax, [rdx]
|
mov rax, [rdx]
|
||||||
|
|
||||||
CallSysRet
|
CallSysRet
|
||||||
|
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
; EFI_STATUS
|
||||||
|
; AllocateRing3Pages (
|
||||||
|
; IN UINTN NumberOfPages,
|
||||||
|
; IN OUT VOID **Memory
|
||||||
|
; );
|
||||||
|
allocateRing3Pages:
|
||||||
|
; Save User (VOID **)Memory on Core SysCall Stack.
|
||||||
|
push r9
|
||||||
|
|
||||||
|
; Replace argument according to UEFI calling convention.
|
||||||
|
mov rcx, r8
|
||||||
|
; Allocate space for (VOID *)Memory on Core SysCall Stack.
|
||||||
|
sub rsp, 8
|
||||||
|
mov rdx, rsp
|
||||||
|
|
||||||
|
; Call Boot Service by FunctionAddress.
|
||||||
|
call [r11]
|
||||||
|
|
||||||
|
DisableSMAP
|
||||||
|
|
||||||
|
; Copy (VOID *)Memory from Core SysCall Stack to User Stack.
|
||||||
|
pop rdx
|
||||||
|
pop r9
|
||||||
|
mov [r9], rdx
|
||||||
|
|
||||||
|
EnableSMAP
|
||||||
|
|
||||||
|
CallSysRet
|
||||||
|
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
; VOID *
|
||||||
|
; AllocateCoreCopy (
|
||||||
|
; IN UINTN AllocationSize,
|
||||||
|
; IN CONST VOID *Buffer
|
||||||
|
; );
|
||||||
|
allocateCoreCopy:
|
||||||
|
DisableSMAP
|
||||||
|
|
||||||
|
; Replace argument according to UEFI calling convention.
|
||||||
|
mov rcx, r8
|
||||||
|
mov rdx, r9
|
||||||
|
|
||||||
|
; Call Boot Service by FunctionAddress.
|
||||||
|
call [r11]
|
||||||
|
|
||||||
|
EnableSMAP
|
||||||
|
|
||||||
|
CallSysRet
|
||||||
|
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
; EFI_STATUS
|
||||||
|
; LocateProtocol (
|
||||||
|
; IN EFI_GUID *Protocol,
|
||||||
|
; IN VOID *Registration OPTIONAL,
|
||||||
|
; OUT VOID **Interface
|
||||||
|
; );
|
||||||
|
locateProtocol:
|
||||||
|
; Replace argument according to UEFI calling convention.
|
||||||
|
mov rcx, r8
|
||||||
|
mov rdx, r9
|
||||||
|
; Allocate space for (VOID *)Interface on Core SysCall Stack.
|
||||||
|
sub rsp, 8
|
||||||
|
mov r8, rsp
|
||||||
|
|
||||||
|
; Call Boot Service by FunctionAddress.
|
||||||
|
call [r11]
|
||||||
|
|
||||||
|
DisableSMAP
|
||||||
|
|
||||||
|
; Copy (VOID *)Interface from Core SysCall Stack to User Stack.
|
||||||
|
pop rcx
|
||||||
|
mov rdx, [rbp + 8] ; rdx = User rsp
|
||||||
|
mov [rdx + 8*4], rcx ; 5th argument of SysCall (SysCallLocateProtocol)
|
||||||
|
|
||||||
|
EnableSMAP
|
||||||
|
|
||||||
|
CallSysRet
|
||||||
|
|
||||||
SECTION .data
|
SECTION .data
|
||||||
|
|
||||||
|
@ -5,14 +5,22 @@
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SysCallReadMemory = 0,
|
||||||
|
SysCallAllocateRing3Pages = 1,
|
||||||
|
SysCallAllocateCoreCopy = 2,
|
||||||
|
SysCallLocateProtocol = 3,
|
||||||
|
SysCallMax
|
||||||
|
} SYS_CALL_TYPE;
|
||||||
|
|
||||||
UINTN
|
UINTN
|
||||||
EFIAPI
|
EFIAPI
|
||||||
SysCall (
|
SysCall (
|
||||||
|
IN UINT8 Type,
|
||||||
IN UINTN FunctionAddress,
|
IN UINTN FunctionAddress,
|
||||||
...
|
...
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Raise the task priority level to the new level.
|
Raise the task priority level to the new level.
|
||||||
High level is implemented by disabling processor interrupts.
|
High level is implemented by disabling processor interrupts.
|
||||||
|
@ -94,7 +94,7 @@ UefiBootServicesTableLibConstructor (
|
|||||||
// Cache pointer to the EFI Boot Services Table
|
// Cache pointer to the EFI Boot Services Table
|
||||||
//
|
//
|
||||||
mCoreBS = (EFI_BOOT_SERVICES *)SysCall (
|
mCoreBS = (EFI_BOOT_SERVICES *)SysCall (
|
||||||
0,
|
SysCallReadMemory,
|
||||||
(UINTN)SystemTable + OFFSET_OF (EFI_SYSTEM_TABLE, BootServices)
|
(UINTN)SystemTable + OFFSET_OF (EFI_SYSTEM_TABLE, BootServices)
|
||||||
);
|
);
|
||||||
ASSERT (mCoreBS != NULL);
|
ASSERT (mCoreBS != NULL);
|
||||||
@ -504,16 +504,31 @@ EFI_STATUS
|
|||||||
EFIAPI
|
EFIAPI
|
||||||
Ring3LocateProtocol (
|
Ring3LocateProtocol (
|
||||||
IN EFI_GUID *Protocol,
|
IN EFI_GUID *Protocol,
|
||||||
IN VOID *Registration OPTIONAL,
|
IN VOID *CoreRegistration OPTIONAL,
|
||||||
OUT VOID **Interface
|
OUT VOID **Interface
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
EFI_GUID *CoreProtocol;
|
||||||
|
|
||||||
|
EFI_DEVICE_PATH_UTILITIES_PROTOCOL *UserProtocol;
|
||||||
|
|
||||||
|
CoreProtocol = (VOID *)SysCall (
|
||||||
|
SysCallAllocateCoreCopy,
|
||||||
|
(UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, AllocateCoreCopy),
|
||||||
|
sizeof (EFI_GUID),
|
||||||
|
Protocol
|
||||||
|
);
|
||||||
|
if (CoreProtocol == NULL) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate core copy of the Protocol variable.\n"));
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
Status = (EFI_STATUS)SysCall (
|
Status = (EFI_STATUS)SysCall (
|
||||||
|
SysCallLocateProtocol,
|
||||||
(UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, LocateProtocol),
|
(UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, LocateProtocol),
|
||||||
Protocol,
|
CoreProtocol,
|
||||||
Registration,
|
CoreRegistration,
|
||||||
Interface
|
Interface
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
@ -522,11 +537,10 @@ Ring3LocateProtocol (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) {
|
if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) {
|
||||||
EFI_DEVICE_PATH_UTILITIES_PROTOCOL *UserProtocol;
|
|
||||||
|
|
||||||
mCoreDevicePathUtilitiesProtocol = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface;
|
mCoreDevicePathUtilitiesProtocol = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface;
|
||||||
|
|
||||||
Status = (EFI_STATUS)SysCall (
|
Status = (EFI_STATUS)SysCall (
|
||||||
|
SysCallAllocateRing3Pages,
|
||||||
(UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, AllocateRing3Pages),
|
(UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, AllocateRing3Pages),
|
||||||
EFI_SIZE_TO_PAGES (sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL)),
|
EFI_SIZE_TO_PAGES (sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL)),
|
||||||
(VOID **)&UserProtocol
|
(VOID **)&UserProtocol
|
||||||
|
@ -10,13 +10,14 @@
|
|||||||
; UINTN
|
; UINTN
|
||||||
; EFIAPI
|
; EFIAPI
|
||||||
; SysCall (
|
; SysCall (
|
||||||
|
; IN UINT8 Type,
|
||||||
; IN UINTN FunctionAddress,
|
; IN UINTN FunctionAddress,
|
||||||
; ...
|
; ...
|
||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
global ASM_PFX(SysCall)
|
global ASM_PFX(SysCall)
|
||||||
ASM_PFX(SysCall):
|
ASM_PFX(SysCall):
|
||||||
; Save FunctionAddress for CoreBootServices().
|
; Save Type for CoreBootServices().
|
||||||
mov r10, rcx
|
mov r10, rcx
|
||||||
|
|
||||||
; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX.
|
; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user