mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-23 13:44:33 +02:00
Ring3: Added SYSCALL draft.
This commit is contained in:
parent
233a5cff09
commit
6502e73b0d
@ -9,6 +9,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||||||
#include "DxeMain.h"
|
#include "DxeMain.h"
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
|
|
||||||
|
#include <Register/Intel/ArchitecturalMsr.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
// Module Globals
|
// Module Globals
|
||||||
//
|
//
|
||||||
@ -1599,6 +1601,7 @@ CoreStartImage (
|
|||||||
VOID *BaseOfStack;
|
VOID *BaseOfStack;
|
||||||
VOID *TopOfStack;
|
VOID *TopOfStack;
|
||||||
UINTN SizeOfStack;
|
UINTN SizeOfStack;
|
||||||
|
UINT64 Msr;
|
||||||
|
|
||||||
Handle = ImageHandle;
|
Handle = ImageHandle;
|
||||||
|
|
||||||
@ -1713,6 +1716,7 @@ CoreStartImage (
|
|||||||
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, "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));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor()
|
// Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor()
|
||||||
@ -1723,6 +1727,19 @@ CoreStartImage (
|
|||||||
EFI_MEMORY_XP | EFI_MEMORY_USER
|
EFI_MEMORY_XP | EFI_MEMORY_USER
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize MSR_IA32_STAR and MSR_IA32_LSTAR for SYSCALL and SYSRET.
|
||||||
|
//
|
||||||
|
Msr = ((((UINT64)RING3_CODE64_SEL - 16) << 16) | (UINT64)RING0_CODE64_SEL) << 32;
|
||||||
|
AsmWriteMsr64 (MSR_IA32_STAR, Msr);
|
||||||
|
|
||||||
|
Msr = (UINT64)(UINTN)CoreBootServices;
|
||||||
|
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,
|
||||||
|
@ -22,7 +22,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
#include <Register/Intel/ArchitecturalMsr.h>
|
||||||
#include <Register/Intel/Cpuid.h>
|
#include <Register/Intel/Cpuid.h>
|
||||||
|
|
||||||
#include "DxeIpl.h"
|
#include "DxeIpl.h"
|
||||||
#include "VirtualMemory.h"
|
#include "VirtualMemory.h"
|
||||||
|
|
||||||
@ -705,8 +707,11 @@ CreateIdentityMappingPageTables (
|
|||||||
IA32_CR4 Cr4;
|
IA32_CR4 Cr4;
|
||||||
IA32_EFLAGS32 Eflags;
|
IA32_EFLAGS32 Eflags;
|
||||||
UINT32 Ebx;
|
UINT32 Ebx;
|
||||||
|
UINT32 Edx;
|
||||||
|
MSR_IA32_EFER_REGISTER MsrEfer;
|
||||||
|
|
||||||
Ebx = 0;
|
Ebx = 0;
|
||||||
|
Edx = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings
|
// Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings
|
||||||
@ -984,7 +989,11 @@ CreateIdentityMappingPageTables (
|
|||||||
// SMEP and SMAP must be supported.
|
// SMEP and SMAP must be supported.
|
||||||
//
|
//
|
||||||
AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL);
|
AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL);
|
||||||
if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) {
|
//
|
||||||
|
// SYSCALL and SYSRET must be also supported.
|
||||||
|
//
|
||||||
|
AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx);
|
||||||
|
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;
|
||||||
@ -997,6 +1006,12 @@ CreateIdentityMappingPageTables (
|
|||||||
//
|
//
|
||||||
Eflags.Bits.IOPL = 3;
|
Eflags.Bits.IOPL = 3;
|
||||||
AsmWriteEflags (Eflags.UintN);
|
AsmWriteEflags (Eflags.UintN);
|
||||||
|
//
|
||||||
|
// Enable SYSCALL and SYSRET
|
||||||
|
//
|
||||||
|
MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER);
|
||||||
|
MsrEfer.Bits.SCE = 1;
|
||||||
|
AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (UINTN)PageMap;
|
return (UINTN)PageMap;
|
||||||
|
@ -5574,16 +5574,17 @@ typedef struct {
|
|||||||
DATA_SEGMENT_32 SysData;
|
DATA_SEGMENT_32 SysData;
|
||||||
CODE_SEGMENT_32 SysCode;
|
CODE_SEGMENT_32 SysCode;
|
||||||
CODE_SEGMENT_32 SysCode16;
|
CODE_SEGMENT_32 SysCode16;
|
||||||
DATA_SEGMENT_32 LinearData64;
|
|
||||||
CODE_SEGMENT_64 LinearCode64;
|
CODE_SEGMENT_64 LinearCode64;
|
||||||
|
DATA_SEGMENT_32 LinearData64;
|
||||||
SEGMENT_DESCRIPTOR Spare5;
|
SEGMENT_DESCRIPTOR Spare5;
|
||||||
DATA_SEGMENT_32 Ring3Data64;
|
DATA_SEGMENT_32 Ring3Data64;
|
||||||
CODE_SEGMENT_64 Ring3Code64;
|
CODE_SEGMENT_64 Ring3Code64;
|
||||||
// CALL_GATE_64 FromRing3ToRing0;
|
|
||||||
} GDT;
|
} GDT;
|
||||||
|
|
||||||
#pragma pack ()
|
#pragma pack ()
|
||||||
|
|
||||||
|
#define RING0_DATA64_SEL OFFSET_OF (GDT, LinearData64)
|
||||||
|
#define RING0_CODE64_SEL OFFSET_OF (GDT, LinearCode64)
|
||||||
#define RING3_DATA64_SEL OFFSET_OF (GDT, Ring3Data64)
|
#define RING3_DATA64_SEL OFFSET_OF (GDT, Ring3Data64)
|
||||||
#define RING3_CODE64_SEL OFFSET_OF (GDT, Ring3Code64)
|
#define RING3_CODE64_SEL OFFSET_OF (GDT, Ring3Code64)
|
||||||
|
|
||||||
@ -6595,6 +6596,13 @@ AsmReadEflags (
|
|||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
CoreBootServices (
|
||||||
|
IN UINTN FunctionAddress,
|
||||||
|
...
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reads the current value of the Control Register 0 (CR0).
|
Reads the current value of the Control Register 0 (CR0).
|
||||||
|
|
||||||
|
@ -91,3 +91,49 @@ o16 mov gs, ax
|
|||||||
|
|
||||||
; Pass control to user image
|
; Pass control to user image
|
||||||
retfq
|
retfq
|
||||||
|
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
; UINTN
|
||||||
|
; EFIAPI
|
||||||
|
; CoreBootServices (
|
||||||
|
; IN UINTN FunctionAddress,
|
||||||
|
; ...
|
||||||
|
; );
|
||||||
|
;
|
||||||
|
; (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, ...
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
global ASM_PFX(CoreBootServices)
|
||||||
|
ASM_PFX(CoreBootServices):
|
||||||
|
cmp r10, 0
|
||||||
|
je readMemory
|
||||||
|
|
||||||
|
; Save return address and RFLAGS for SYSRET.
|
||||||
|
mov [rsp], rcx
|
||||||
|
mov [rsp + 8], r11
|
||||||
|
|
||||||
|
; Replace argument according to UEFI calling convention.
|
||||||
|
mov rcx, rdx
|
||||||
|
mov rdx, r8
|
||||||
|
mov r8, r9
|
||||||
|
mov r9, [rsp + 8*3]
|
||||||
|
|
||||||
|
; Call Boot Service by FunctionAddress.
|
||||||
|
call r10
|
||||||
|
|
||||||
|
; Prepare SYSRET arguments.
|
||||||
|
mov rcx, [rsp]
|
||||||
|
mov r11, [rsp + 8]
|
||||||
|
|
||||||
|
; 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.
|
||||||
|
|
||||||
|
readMemory:
|
||||||
|
mov rax, [rdx]
|
||||||
|
o64 sysret
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
|
/** @file
|
||||||
|
|
||||||
|
Copyright (c) 2024, Mikhail Krichanov. All rights reserved.
|
||||||
|
SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
SysCall (
|
||||||
|
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.
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <Uefi.h>
|
#include <Uefi.h>
|
||||||
|
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
|
||||||
#include "Ring3.h"
|
#include "Ring3.h"
|
||||||
|
|
||||||
@ -66,9 +67,8 @@ EFI_BOOT_SERVICES mBootServices = {
|
|||||||
(EFI_CREATE_EVENT_EX)Ring3CreateEventEx // CreateEventEx
|
(EFI_CREATE_EVENT_EX)Ring3CreateEventEx // CreateEventEx
|
||||||
};
|
};
|
||||||
|
|
||||||
// EFI_HANDLE gImageHandle = NULL;
|
|
||||||
// EFI_SYSTEM_TABLE *gST = NULL;
|
|
||||||
EFI_BOOT_SERVICES *gBS = &mBootServices;
|
EFI_BOOT_SERVICES *gBS = &mBootServices;
|
||||||
|
EFI_BOOT_SERVICES *mCoreBS = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The function constructs Ring 3 wrappers for the EFI_BOOT_SERVICES.
|
The function constructs Ring 3 wrappers for the EFI_BOOT_SERVICES.
|
||||||
@ -86,23 +86,15 @@ UefiBootServicesTableLibConstructor (
|
|||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
// Cache the Image Handle
|
|
||||||
//
|
|
||||||
// gImageHandle = ImageHandle;
|
|
||||||
// ASSERT (gImageHandle != NULL);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Cache pointer to the EFI System Table
|
|
||||||
//
|
|
||||||
// gST = SystemTable;
|
|
||||||
// ASSERT (gST != NULL);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Cache pointer to the EFI Boot Services Table
|
// Cache pointer to the EFI Boot Services Table
|
||||||
//
|
//
|
||||||
// gBS = SystemTable->BootServices;
|
mCoreBS = (EFI_BOOT_SERVICES *)SysCall (
|
||||||
// ASSERT (gBS != NULL);
|
0,
|
||||||
|
(UINTN)SystemTable + OFFSET_OF (EFI_SYSTEM_TABLE, BootServices)
|
||||||
|
);
|
||||||
|
ASSERT (mCoreBS != NULL);
|
||||||
|
// DEBUG ((DEBUG_ERROR, "User: BootServices = %p\n", mCoreBS));
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -512,7 +504,16 @@ Ring3LocateProtocol (
|
|||||||
OUT VOID **Interface
|
OUT VOID **Interface
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return EFI_SUCCESS;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
Status = (EFI_STATUS)SysCall (
|
||||||
|
(UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, LocateProtocol),
|
||||||
|
Protocol,
|
||||||
|
Registration,
|
||||||
|
Interface
|
||||||
|
);
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
|
@ -26,9 +26,12 @@
|
|||||||
Ring3.h
|
Ring3.h
|
||||||
Ring3UefiBootServicesTableLib.c
|
Ring3UefiBootServicesTableLib.c
|
||||||
|
|
||||||
|
[Sources.X64]
|
||||||
|
X64/SysCall.nasm
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
|
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
BaseMemoryLib
|
BaseMemoryLib
|
||||||
|
DebugLib
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
;------------------------------------------------------------------------------
|
||||||
|
; Copyright (c) 2024, Mikhail Krichanov. All rights reserved.
|
||||||
|
; SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
DEFAULT REL
|
||||||
|
SECTION .text
|
||||||
|
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
; UINTN
|
||||||
|
; EFIAPI
|
||||||
|
; SysCall (
|
||||||
|
; IN UINTN FunctionAddress,
|
||||||
|
; ...
|
||||||
|
; );
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
global ASM_PFX(SysCall)
|
||||||
|
ASM_PFX(SysCall):
|
||||||
|
; Save FunctionAddress for CoreBootServices().
|
||||||
|
mov r10, rcx
|
||||||
|
|
||||||
|
; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX.
|
||||||
|
syscall
|
||||||
|
; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11.
|
||||||
|
|
||||||
|
ret
|
@ -129,6 +129,25 @@ STATIC GDT mGdtTemplate = {
|
|||||||
.Granularity = 1,
|
.Granularity = 1,
|
||||||
.BaseAddress_31_24 = 0x0
|
.BaseAddress_31_24 = 0x0
|
||||||
},
|
},
|
||||||
|
.LinearCode64 = {
|
||||||
|
.Reserved1 = 0x0,
|
||||||
|
.Reserved2 = 0x0,
|
||||||
|
|
||||||
|
.Accessed = 0,
|
||||||
|
.Readable = 1,
|
||||||
|
.Conforming = 0,
|
||||||
|
.IsCode = 1,
|
||||||
|
.IsNotSystemSegment = 1,
|
||||||
|
.DescriptorPrivilegeLevel = 0,
|
||||||
|
.SegmentPresent = 1,
|
||||||
|
|
||||||
|
.Reserved3 = 0x0,
|
||||||
|
.Available = 0,
|
||||||
|
.LongMode = 1,
|
||||||
|
.Is32Bit = 0,
|
||||||
|
.Granularity = 1,
|
||||||
|
.Reserved4 = 0x0
|
||||||
|
},
|
||||||
.LinearData64 = {
|
.LinearData64 = {
|
||||||
.SegmentLimit_15_0 = 0xFFFF,
|
.SegmentLimit_15_0 = 0xFFFF,
|
||||||
.BaseAddress_15_0 = 0x0,
|
.BaseAddress_15_0 = 0x0,
|
||||||
@ -149,25 +168,6 @@ STATIC GDT mGdtTemplate = {
|
|||||||
.Granularity = 1,
|
.Granularity = 1,
|
||||||
.BaseAddress_31_24 = 0x0
|
.BaseAddress_31_24 = 0x0
|
||||||
},
|
},
|
||||||
.LinearCode64 = {
|
|
||||||
.Reserved1 = 0x0,
|
|
||||||
.Reserved2 = 0x0,
|
|
||||||
|
|
||||||
.Accessed = 0,
|
|
||||||
.Readable = 1,
|
|
||||||
.Conforming = 0,
|
|
||||||
.IsCode = 1,
|
|
||||||
.IsNotSystemSegment = 1,
|
|
||||||
.DescriptorPrivilegeLevel = 0,
|
|
||||||
.SegmentPresent = 1,
|
|
||||||
|
|
||||||
.Reserved3 = 0x0,
|
|
||||||
.Available = 0,
|
|
||||||
.LongMode = 1,
|
|
||||||
.Is32Bit = 0,
|
|
||||||
.Granularity = 1,
|
|
||||||
.Reserved4 = 0x0
|
|
||||||
},
|
|
||||||
.Spare5 = {
|
.Spare5 = {
|
||||||
.SegmentLimit_15_0 = 0x0,
|
.SegmentLimit_15_0 = 0x0,
|
||||||
.BaseAddress_15_0 = 0x0,
|
.BaseAddress_15_0 = 0x0,
|
||||||
@ -203,7 +203,7 @@ STATIC GDT mGdtTemplate = {
|
|||||||
.Granularity = 1,
|
.Granularity = 1,
|
||||||
.BaseAddress_31_24 = 0x0
|
.BaseAddress_31_24 = 0x0
|
||||||
},
|
},
|
||||||
.Ring3Code64 = { // SetCodeSelector () | 5.8.6 Returning from a Called Procedure
|
.Ring3Code64 = {
|
||||||
.Reserved1 = 0x0,
|
.Reserved1 = 0x0,
|
||||||
.Reserved2 = 0x0,
|
.Reserved2 = 0x0,
|
||||||
|
|
||||||
@ -222,21 +222,6 @@ STATIC GDT mGdtTemplate = {
|
|||||||
.Granularity = 1,
|
.Granularity = 1,
|
||||||
.Reserved4 = 0x0
|
.Reserved4 = 0x0
|
||||||
},
|
},
|
||||||
// .FromRing3ToRing0 = {
|
|
||||||
// .Common.OffsetInSegment_15_0 = 0x?,
|
|
||||||
// .Common.SegmentSelector = (UINT16)LINEAR_CODE64_SEL,
|
|
||||||
//
|
|
||||||
// .Common.ParameterCount = 0,
|
|
||||||
// .Common.Reserved = 0,
|
|
||||||
//
|
|
||||||
// .Common.Type = 0xC,
|
|
||||||
// .Common.IsNotSystemSegment = 0,
|
|
||||||
// .Common.DescriptorPrivilegeLevel = 3,
|
|
||||||
// .Common.SegmentPresent = 1,
|
|
||||||
// .Common.OffsetInSegment_31_16 = 0x?,
|
|
||||||
// .OffsetInSegment_63_31 = 0x?,
|
|
||||||
// .Reserved = 0x0
|
|
||||||
// },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -249,8 +249,6 @@ ArchSetupExceptionStack (
|
|||||||
IdtTable[Vector].Bits.Reserved_0 = (UINT8)(Index + 1);
|
IdtTable[Vector].Bits.Reserved_0 = (UINT8)(Index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tss->RSP0 = %rsp
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Publish GDT
|
// Publish GDT
|
||||||
//
|
//
|
||||||
|
Loading…
x
Reference in New Issue
Block a user