mirror of https://github.com/acidanthera/audk.git
Ring3: Added support for ARM User page table.
This commit is contained in:
parent
d051ccdbe8
commit
75c5b9e27e
|
@ -21,6 +21,16 @@
|
|||
|
||||
#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) \
|
||||
movw Reg, #(Val) & 0xffff ; \
|
||||
movt Reg, #(Val) >> 16
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#------------------------------------------------------------------------------
|
||||
|
||||
#include <Library/PcdLib.h>
|
||||
#include <AsmMacroIoLib.h>
|
||||
|
||||
/*
|
||||
|
||||
|
@ -59,8 +60,10 @@ GCC_ASM_EXPORT(CommonCExceptionHandler)
|
|||
#if !defined(__APPLE__)
|
||||
.fpu neon @ makes vpush/vpop assemble
|
||||
#endif
|
||||
.align 5
|
||||
|
||||
ASM_FUNC_ALIGN(ExceptionHandlerBase, 4096)
|
||||
|
||||
.align 5
|
||||
|
||||
//
|
||||
// This code gets copied to the ARM vector table
|
||||
|
@ -117,6 +120,8 @@ ASM_PFX(UndefinedInstructionEntry):
|
|||
bx R1
|
||||
|
||||
ASM_PFX(SoftwareInterruptEntry):
|
||||
cpsid if
|
||||
isb
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
@ We are already in SVC 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
|
||||
#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
|
||||
tst R4, #4
|
||||
subne SP, SP, #4 @ Adjust SP if not 8-byte aligned
|
||||
|
@ -269,6 +292,19 @@ CommonCExceptionHandler (
|
|||
|
||||
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))
|
||||
vpop {d0-d15}
|
||||
#endif
|
||||
|
@ -290,3 +326,19 @@ CommonCExceptionHandler (
|
|||
add SP,SP,#0x20 @ Clear out the remaining stack space
|
||||
ldmfd SP!,{LR} @ restore the link register for this context
|
||||
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}
|
||||
bx LR
|
||||
|
||||
ASM_FUNC_ALIGN(SysCallBase, 4096)
|
||||
//------------------------------------------------------------------------------
|
||||
// EFI_STATUS
|
||||
// EFIAPI
|
||||
|
@ -63,13 +64,15 @@ call:
|
|||
// (r2) gRing3EntryPoint
|
||||
// (r3) gCoreSysCallStackTop
|
||||
//
|
||||
// (On Core Stack) &CoreSp
|
||||
// (On Core Stack) &CoreSp, gUserPageTable
|
||||
//------------------------------------------------------------------------------
|
||||
ASM_FUNC(ArmCallRing3)
|
||||
// Save registers.
|
||||
push {R4-R12, LR}
|
||||
// R6 is &CoreSp
|
||||
ldr R6, [SP, #0x28]
|
||||
// R7 is gUserPageTable
|
||||
ldr R7, [SP, #0x2C]
|
||||
|
||||
#if (FixedPcdGet32(PcdVFPEnabled))
|
||||
// Save vstm registers in case they are used in optimizations.
|
||||
|
@ -94,10 +97,21 @@ ASM_FUNC(ArmCallRing3)
|
|||
str R5, [R6]
|
||||
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 {R2}
|
||||
rfefd SP
|
||||
|
||||
ASM_FUNC_ALIGN(SysCallEnd, 4096)
|
||||
//------------------------------------------------------------------------------
|
||||
// VOID
|
||||
// EFIAPI
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "DxeMain.h"
|
||||
|
||||
STATIC UINTN mCoreSp;
|
||||
extern UINTN gUartBaseAddress;
|
||||
UINTN gUserPageTable;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
|
@ -21,7 +21,8 @@ ArmCallRing3 (
|
|||
IN VOID *StackPointer,
|
||||
IN VOID *EntryPoint,
|
||||
IN VOID *SysCallStack,
|
||||
IN VOID *CoreStack
|
||||
IN VOID *CoreStack,
|
||||
IN UINTN UserPageTable
|
||||
);
|
||||
|
||||
VOID
|
||||
|
@ -52,6 +53,8 @@ SysCallBootService (
|
|||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS Physical;
|
||||
|
||||
ArmEnableInterrupts ();
|
||||
|
||||
Status = CoreAllocatePages (
|
||||
AllocateAnyPages,
|
||||
EfiRing3MemoryType,
|
||||
|
@ -71,12 +74,6 @@ SysCallBootService (
|
|||
// All remaining arguments are on User Stack.
|
||||
//
|
||||
CopyMem ((VOID *)((UINTN)Physical + 5 * sizeof (UINTN)), (VOID *)UserRsp, 4 * sizeof (UINTN));
|
||||
|
||||
SetUefiImageMemoryAttributes (
|
||||
gUartBaseAddress,
|
||||
EFI_PAGE_SIZE,
|
||||
EFI_MEMORY_XP
|
||||
);
|
||||
ForbidSupervisorAccessToUserMemory ();
|
||||
|
||||
Status = CallBootService (
|
||||
|
@ -89,11 +86,7 @@ SysCallBootService (
|
|||
//
|
||||
CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)));
|
||||
|
||||
SetUefiImageMemoryAttributes (
|
||||
gUartBaseAddress,
|
||||
EFI_PAGE_SIZE,
|
||||
EFI_MEMORY_XP | EFI_MEMORY_USER
|
||||
);
|
||||
ArmDisableInterrupts ();
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@ -141,6 +134,7 @@ InitializeMsr (
|
|||
}
|
||||
|
||||
InitializeSysCallHandler (SysCallBootService);
|
||||
SetExceptionAddresses (NULL, 0);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -171,5 +165,5 @@ CallRing3 (
|
|||
IN RING3_CALL_DATA *Data
|
||||
)
|
||||
{
|
||||
return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp);
|
||||
return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp, gUserPageTable);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue