mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-27 15:44:04 +02:00
Ring3: Added CoreSysCallStack.
This commit is contained in:
parent
e36fd7b639
commit
2fe010f40b
@ -27,6 +27,7 @@ STATIC EFI_EVENT mPeCoffEmuProtocolRegistrationEvent;
|
|||||||
STATIC VOID *mPeCoffEmuProtocolNotifyRegistration;
|
STATIC VOID *mPeCoffEmuProtocolNotifyRegistration;
|
||||||
|
|
||||||
extern BOOLEAN gBdsStarted;
|
extern BOOLEAN gBdsStarted;
|
||||||
|
extern VOID *gCoreSysCallStackTop;
|
||||||
|
|
||||||
//
|
//
|
||||||
// This code is needed to build the Image handle for the DXE Core
|
// This code is needed to build the Image handle for the DXE Core
|
||||||
@ -1700,23 +1701,41 @@ CoreStartImage (
|
|||||||
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes);
|
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes);
|
||||||
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
|
||||||
|
|
||||||
|
SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allocate 128KB for the Core SysCall Stack.
|
||||||
|
//
|
||||||
|
BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE));
|
||||||
|
ASSERT (BaseOfStack != NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Compute the top of the allocated stack. Pre-allocate a UINTN for safety.
|
||||||
|
//
|
||||||
|
TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT);
|
||||||
|
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
|
||||||
|
|
||||||
|
gCoreSysCallStackTop = TopOfStack;
|
||||||
|
DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop));
|
||||||
|
|
||||||
|
SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate 128KB for the User Stack.
|
// Allocate 128KB for the User Stack.
|
||||||
//
|
//
|
||||||
BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE));
|
BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE));
|
||||||
ASSERT (BaseOfStack != NULL);
|
ASSERT (BaseOfStack != NULL);
|
||||||
|
|
||||||
SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE;
|
|
||||||
|
|
||||||
SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Compute the top of the allocated stack. Pre-allocate a UINTN for safety.
|
// Compute the top of the allocated stack. Pre-allocate a UINTN for safety.
|
||||||
//
|
//
|
||||||
TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT);
|
TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT);
|
||||||
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
|
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
|
||||||
// DEBUG ((DEBUG_ERROR, "RING3_CODE64_SEL = 0x%x RING3_DATA64_SEL = 0x%x\n", (UINT16)RING3_CODE64_SEL, (UINT16)RING3_DATA64_SEL));
|
|
||||||
// DEBUG ((DEBUG_ERROR, "Core: BootServices = %p\n", Image->Info.SystemTable->BootServices));
|
SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER);
|
||||||
|
DEBUG ((DEBUG_ERROR, "Core: UserTopOfStack = %p\n", TopOfStack));
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_ERROR, "Core: BootServices = %p\n", Image->Info.SystemTable->BootServices));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor()
|
// Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor()
|
||||||
@ -1736,10 +1755,6 @@ CoreStartImage (
|
|||||||
Msr = (UINT64)(UINTN)CoreBootServices;
|
Msr = (UINT64)(UINTN)CoreBootServices;
|
||||||
AsmWriteMsr64 (MSR_IA32_LSTAR, Msr);
|
AsmWriteMsr64 (MSR_IA32_LSTAR, Msr);
|
||||||
|
|
||||||
// protection keys
|
|
||||||
// Software can access the old stack, if necessary, by referencing the old
|
|
||||||
// stack-segment selector and stack pointer saved on the new process stack.
|
|
||||||
|
|
||||||
EnterUserImage (
|
EnterUserImage (
|
||||||
(SWITCH_STACK_ENTRY_POINT)(UINTN)Image->EntryPoint,
|
(SWITCH_STACK_ENTRY_POINT)(UINTN)Image->EntryPoint,
|
||||||
ImageHandle,
|
ImageHandle,
|
||||||
|
@ -998,7 +998,7 @@ CreateIdentityMappingPageTables (
|
|||||||
AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx);
|
AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx);
|
||||||
if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) {
|
if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) {
|
||||||
Cr4.UintN = AsmReadCr4 ();
|
Cr4.UintN = AsmReadCr4 ();
|
||||||
Cr4.Bits.SMAP = 1;
|
// Cr4.Bits.SMAP = 1;
|
||||||
Cr4.Bits.SMEP = 1;
|
Cr4.Bits.SMEP = 1;
|
||||||
AsmWriteCr4 (Cr4.UintN);
|
AsmWriteCr4 (Cr4.UintN);
|
||||||
|
|
||||||
@ -1010,7 +1010,7 @@ CreateIdentityMappingPageTables (
|
|||||||
Eflags.Bits.IOPL = 3;
|
Eflags.Bits.IOPL = 3;
|
||||||
AsmWriteEflags (Eflags.UintN);
|
AsmWriteEflags (Eflags.UintN);
|
||||||
//
|
//
|
||||||
// Enable SYSCALL and SYSRET
|
// Enable SYSCALL and SYSRET.
|
||||||
//
|
//
|
||||||
MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER);
|
MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER);
|
||||||
MsrEfer.Bits.SCE = 1;
|
MsrEfer.Bits.SCE = 1;
|
||||||
|
@ -113,22 +113,45 @@ ASM_PFX(CoreBootServices):
|
|||||||
cmp r10, 0
|
cmp r10, 0
|
||||||
je readMemory
|
je readMemory
|
||||||
|
|
||||||
|
mov ax, ss
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
|
||||||
|
; Save User Stack pointer and switch to Core SysCall Stack.
|
||||||
|
mov rax, [ASM_PFX(gCoreSysCallStackTop)]
|
||||||
|
sub rax, 8
|
||||||
|
mov [rax], rsp
|
||||||
|
mov rsp, rax
|
||||||
|
|
||||||
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
|
||||||
; Save return address and RFLAGS for SYSRET.
|
; Save return address and RFLAGS for SYSRET.
|
||||||
mov [rsp], rcx
|
push rcx
|
||||||
mov [rsp + 8], r11
|
push r11
|
||||||
|
|
||||||
; Replace argument according to UEFI calling convention.
|
; Replace argument according to UEFI calling convention.
|
||||||
mov rcx, rdx
|
mov rcx, rdx
|
||||||
mov rdx, r8
|
mov rdx, r8
|
||||||
mov r8, r9
|
mov r8, r9
|
||||||
mov r9, [rsp + 8*3]
|
; mov r9, [rax + 8*3]
|
||||||
|
; mov r11, [rax + 8*4]
|
||||||
|
; push r11
|
||||||
|
; ...
|
||||||
|
|
||||||
; Call Boot Service by FunctionAddress.
|
; Call Boot Service by FunctionAddress.
|
||||||
call r10
|
call r10
|
||||||
|
|
||||||
; Prepare SYSRET arguments.
|
; Prepare SYSRET arguments.
|
||||||
mov rcx, [rsp]
|
pop r11
|
||||||
mov r11, [rsp + 8]
|
pop rcx
|
||||||
|
|
||||||
|
; Switch to User Stack.
|
||||||
|
pop rbp
|
||||||
|
pop rdx
|
||||||
|
mov rsp, rdx
|
||||||
|
|
||||||
; 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.
|
||||||
o64 sysret
|
o64 sysret
|
||||||
@ -137,3 +160,10 @@ o64 sysret
|
|||||||
readMemory:
|
readMemory:
|
||||||
mov rax, [rdx]
|
mov rax, [rdx]
|
||||||
o64 sysret
|
o64 sysret
|
||||||
|
|
||||||
|
|
||||||
|
SECTION .data
|
||||||
|
|
||||||
|
global ASM_PFX(gCoreSysCallStackTop)
|
||||||
|
ASM_PFX(gCoreSysCallStackTop):
|
||||||
|
resq 1
|
||||||
|
@ -94,7 +94,7 @@ UefiBootServicesTableLibConstructor (
|
|||||||
(UINTN)SystemTable + OFFSET_OF (EFI_SYSTEM_TABLE, BootServices)
|
(UINTN)SystemTable + OFFSET_OF (EFI_SYSTEM_TABLE, BootServices)
|
||||||
);
|
);
|
||||||
ASSERT (mCoreBS != NULL);
|
ASSERT (mCoreBS != NULL);
|
||||||
// DEBUG ((DEBUG_ERROR, "User: BootServices = %p\n", mCoreBS));
|
DEBUG ((DEBUG_ERROR, "User: BootServices = %p\n", mCoreBS));
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user