mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-26 23:24:03 +02:00
Ring3: Added support for ARM User page table.
This commit is contained in:
parent
1c10e31d45
commit
f4244d8d44
@ -11,6 +11,7 @@
|
|||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <Library/PcdLib.h>
|
#include <Library/PcdLib.h>
|
||||||
|
#include <AsmMacroIoLib.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
@ -59,8 +60,10 @@ GCC_ASM_EXPORT(CommonCExceptionHandler)
|
|||||||
#if !defined(__APPLE__)
|
#if !defined(__APPLE__)
|
||||||
.fpu neon @ makes vpush/vpop assemble
|
.fpu neon @ makes vpush/vpop assemble
|
||||||
#endif
|
#endif
|
||||||
.align 5
|
|
||||||
|
|
||||||
|
ASM_FUNC_ALIGN(ExceptionHandlerBase, 4096)
|
||||||
|
|
||||||
|
.align 5
|
||||||
|
|
||||||
//
|
//
|
||||||
// This code gets copied to the ARM vector table
|
// This code gets copied to the ARM vector table
|
||||||
@ -117,6 +120,8 @@ ASM_PFX(UndefinedInstructionEntry):
|
|||||||
bx R1
|
bx R1
|
||||||
|
|
||||||
ASM_PFX(SoftwareInterruptEntry):
|
ASM_PFX(SoftwareInterruptEntry):
|
||||||
|
cpsid if
|
||||||
|
isb
|
||||||
srsdb #0x13! @ Store return state on SVC stack
|
srsdb #0x13! @ Store return state on SVC stack
|
||||||
@ We are already in SVC mode
|
@ We are already in SVC mode
|
||||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||||
@ -250,6 +255,24 @@ NoAdjustNeeded:
|
|||||||
vpush {d0-d15} @ save vstm registers in case they are used in optimizations
|
vpush {d0-d15} @ save vstm registers in case they are used in optimizations
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ldr R5, [SP, #0x40] @ Saved Processor Status Register
|
||||||
|
and R5, R5, #0xF
|
||||||
|
cmp R5, 0 @ Check whether EL0 process was interrupted
|
||||||
|
bne NoTTBR0Switch
|
||||||
|
mrc p15,0,R5,c2,c0,0 @ R5 == TTBR0
|
||||||
|
ADRL (R6, UserPageTable)
|
||||||
|
str R5, [R6]
|
||||||
|
and R5, R5, #0x7F @ Preserve TTBR0 attributes
|
||||||
|
LDRL (R6, ASM_PFX(CorePageTable))
|
||||||
|
orr R6, R6, R5 @ Assign TTBR0 attributes
|
||||||
|
mcr p15,0,R6,c2,c0,0 @ TTBR0 == R6
|
||||||
|
mcr p15,0,r0,c8,c7,0 @ TLBIALL, TLB Invalidate All.
|
||||||
|
mcr p15,0,r0,c7,c5,6 @ BPIALL, Branch Predictor Invalidate All.
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
|
|
||||||
|
NoTTBR0Switch:
|
||||||
|
|
||||||
mov R4, SP @ Save current SP
|
mov R4, SP @ Save current SP
|
||||||
tst R4, #4
|
tst R4, #4
|
||||||
subne SP, SP, #4 @ Adjust SP if not 8-byte aligned
|
subne SP, SP, #4 @ Adjust SP if not 8-byte aligned
|
||||||
@ -269,6 +292,19 @@ CommonCExceptionHandler (
|
|||||||
|
|
||||||
mov SP, R4 @ Restore SP
|
mov SP, R4 @ Restore SP
|
||||||
|
|
||||||
|
ldr R4, [SP, #0x40] @ Saved Processor Status Register
|
||||||
|
and R4, R4, #0xF
|
||||||
|
cmp R4, 0 @ Check whether EL0 process was interrupted
|
||||||
|
bne NoTTBR0Switch2
|
||||||
|
LDRL (R4, UserPageTable)
|
||||||
|
mcr p15,0,R4,c2,c0,0 @ TTBR0 == R4
|
||||||
|
mcr p15,0,r0,c8,c7,0 @ TLBIALL, TLB Invalidate All.
|
||||||
|
mcr p15,0,r0,c7,c5,6 @ BPIALL, Branch Predictor Invalidate All.
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
|
|
||||||
|
NoTTBR0Switch2:
|
||||||
|
|
||||||
#if (FixedPcdGet32(PcdVFPEnabled))
|
#if (FixedPcdGet32(PcdVFPEnabled))
|
||||||
vpop {d0-d15}
|
vpop {d0-d15}
|
||||||
#endif
|
#endif
|
||||||
@ -290,3 +326,19 @@ CommonCExceptionHandler (
|
|||||||
add SP,SP,#0x20 @ Clear out the remaining stack space
|
add SP,SP,#0x20 @ Clear out the remaining stack space
|
||||||
ldmfd SP!,{LR} @ restore the link register for this context
|
ldmfd SP!,{LR} @ restore the link register for this context
|
||||||
rfefd SP! @ return from exception via srsfd stack slot
|
rfefd SP! @ return from exception via srsfd stack slot
|
||||||
|
|
||||||
|
ASM_FUNC_ALIGN(ExceptionHandlerFinal, 4096)
|
||||||
|
|
||||||
|
.data
|
||||||
|
|
||||||
|
.global ASM_PFX(CorePageTable)
|
||||||
|
.balign 4096
|
||||||
|
ASM_PFX(CorePageTable):
|
||||||
|
.ds.l 1
|
||||||
|
|
||||||
|
UserPageTable:
|
||||||
|
.ds.l 1
|
||||||
|
|
||||||
|
.balign 4096
|
||||||
|
Padding:
|
||||||
|
.ds.b 1
|
||||||
|
@ -51,6 +51,7 @@ call:
|
|||||||
pop {R4-R8, LR}
|
pop {R4-R8, LR}
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
|
ASM_FUNC_ALIGN(SysCallBase, 4096)
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// EFI_STATUS
|
// EFI_STATUS
|
||||||
// EFIAPI
|
// EFIAPI
|
||||||
@ -63,13 +64,15 @@ call:
|
|||||||
// (r2) gRing3EntryPoint
|
// (r2) gRing3EntryPoint
|
||||||
// (r3) gCoreSysCallStackTop
|
// (r3) gCoreSysCallStackTop
|
||||||
//
|
//
|
||||||
// (On Core Stack) &CoreSp
|
// (On Core Stack) &CoreSp, gUserPageTable
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
ASM_FUNC(ArmCallRing3)
|
ASM_FUNC(ArmCallRing3)
|
||||||
// Save registers.
|
// Save registers.
|
||||||
push {R4-R12, LR}
|
push {R4-R12, LR}
|
||||||
// R6 is &CoreSp
|
// R6 is &CoreSp
|
||||||
ldr R6, [SP, #0x28]
|
ldr R6, [SP, #0x28]
|
||||||
|
// R7 is gUserPageTable
|
||||||
|
ldr R7, [SP, #0x2C]
|
||||||
|
|
||||||
#if (FixedPcdGet32(PcdVFPEnabled))
|
#if (FixedPcdGet32(PcdVFPEnabled))
|
||||||
// Save vstm registers in case they are used in optimizations.
|
// Save vstm registers in case they are used in optimizations.
|
||||||
@ -94,10 +97,21 @@ ASM_FUNC(ArmCallRing3)
|
|||||||
str R5, [R6]
|
str R5, [R6]
|
||||||
mov SP, R3
|
mov SP, R3
|
||||||
|
|
||||||
|
// Switch to UserPageTable.
|
||||||
|
mrc p15,0,R8,c2,c0,0 // R8 == TTBR0
|
||||||
|
and R8, R8, #0x7F // Preserve Core TTBR0 attributes.
|
||||||
|
orr R7, R7, R8 // Assign Core attributes to UserPageTable.
|
||||||
|
mcr p15,0,R7,c2,c0,0 // TTBR0 == UserPageTable
|
||||||
|
mcr p15,0,r0,c8,c7,0 // TLBIALL, TLB Invalidate All.
|
||||||
|
mcr p15,0,r0,c7,c5,6 // BPIALL, Branch Predictor Invalidate All.
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
|
|
||||||
push {R4}
|
push {R4}
|
||||||
push {R2}
|
push {R2}
|
||||||
rfefd SP
|
rfefd SP
|
||||||
|
|
||||||
|
ASM_FUNC_ALIGN(SysCallEnd, 4096)
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// VOID
|
// VOID
|
||||||
// EFIAPI
|
// EFIAPI
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include "DxeMain.h"
|
#include "DxeMain.h"
|
||||||
|
|
||||||
STATIC UINTN mCoreSp;
|
STATIC UINTN mCoreSp;
|
||||||
extern UINTN gUartBaseAddress;
|
UINTN gUserPageTable;
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
@ -21,7 +21,8 @@ ArmCallRing3 (
|
|||||||
IN VOID *StackPointer,
|
IN VOID *StackPointer,
|
||||||
IN VOID *EntryPoint,
|
IN VOID *EntryPoint,
|
||||||
IN VOID *SysCallStack,
|
IN VOID *SysCallStack,
|
||||||
IN VOID *CoreStack
|
IN VOID *CoreStack,
|
||||||
|
IN UINTN UserPageTable
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
@ -52,6 +53,8 @@ SysCallBootService (
|
|||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_PHYSICAL_ADDRESS Physical;
|
EFI_PHYSICAL_ADDRESS Physical;
|
||||||
|
|
||||||
|
ArmEnableInterrupts ();
|
||||||
|
|
||||||
Status = CoreAllocatePages (
|
Status = CoreAllocatePages (
|
||||||
AllocateAnyPages,
|
AllocateAnyPages,
|
||||||
EfiRing3MemoryType,
|
EfiRing3MemoryType,
|
||||||
@ -71,12 +74,6 @@ SysCallBootService (
|
|||||||
// All remaining arguments are on User Stack.
|
// All remaining arguments are on User Stack.
|
||||||
//
|
//
|
||||||
CopyMem ((VOID *)((UINTN)Physical + 5 * sizeof (UINTN)), (VOID *)UserRsp, 4 * sizeof (UINTN));
|
CopyMem ((VOID *)((UINTN)Physical + 5 * sizeof (UINTN)), (VOID *)UserRsp, 4 * sizeof (UINTN));
|
||||||
|
|
||||||
SetUefiImageMemoryAttributes (
|
|
||||||
gUartBaseAddress,
|
|
||||||
EFI_PAGE_SIZE,
|
|
||||||
EFI_MEMORY_XP
|
|
||||||
);
|
|
||||||
ForbidSupervisorAccessToUserMemory ();
|
ForbidSupervisorAccessToUserMemory ();
|
||||||
|
|
||||||
Status = CallBootService (
|
Status = CallBootService (
|
||||||
@ -89,11 +86,7 @@ SysCallBootService (
|
|||||||
//
|
//
|
||||||
CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)));
|
CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)));
|
||||||
|
|
||||||
SetUefiImageMemoryAttributes (
|
ArmDisableInterrupts ();
|
||||||
gUartBaseAddress,
|
|
||||||
EFI_PAGE_SIZE,
|
|
||||||
EFI_MEMORY_XP | EFI_MEMORY_USER
|
|
||||||
);
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
@ -141,6 +134,7 @@ InitializeMsr (
|
|||||||
}
|
}
|
||||||
|
|
||||||
InitializeSysCallHandler (SysCallBootService);
|
InitializeSysCallHandler (SysCallBootService);
|
||||||
|
SetExceptionAddresses (NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
@ -171,5 +165,5 @@ CallRing3 (
|
|||||||
IN RING3_CALL_DATA *Data
|
IN RING3_CALL_DATA *Data
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp);
|
return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp, gUserPageTable);
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,16 @@
|
|||||||
|
|
||||||
#define ASM_FUNC(Name) _ASM_FUNC(ASM_PFX(Name), .text. ## Name)
|
#define ASM_FUNC(Name) _ASM_FUNC(ASM_PFX(Name), .text. ## Name)
|
||||||
|
|
||||||
|
#define _ASM_FUNC_ALIGN(Name, Section, Align) \
|
||||||
|
.global Name ; \
|
||||||
|
.section #Section, "ax" ; \
|
||||||
|
.type Name, %function ; \
|
||||||
|
.balign Align ; \
|
||||||
|
Name:
|
||||||
|
|
||||||
|
#define ASM_FUNC_ALIGN(Name, Align) \
|
||||||
|
_ASM_FUNC_ALIGN(ASM_PFX(Name), .text. ## Name, Align)
|
||||||
|
|
||||||
#define MOV32(Reg, Val) \
|
#define MOV32(Reg, Val) \
|
||||||
movw Reg, #(Val) & 0xffff ; \
|
movw Reg, #(Val) & 0xffff ; \
|
||||||
movt Reg, #(Val) >> 16
|
movt Reg, #(Val) >> 16
|
||||||
|
Loading…
x
Reference in New Issue
Block a user