Skip to content

Commit

Permalink
Ring3: Placed UnicodeCollation driver into User space.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikhail Krichanov committed Jan 20, 2025
1 parent cd65706 commit 93625d5
Show file tree
Hide file tree
Showing 13 changed files with 190 additions and 104 deletions.
31 changes: 14 additions & 17 deletions ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@
UINT64 ESR; 0x318 // Exception syndrome register
UINT64 FAR; 0x320 // Fault Address Register
UINT64 Type; 0x328 // Exception Type
UINT64 TTBR0; 0x330 // User Page Table
UINT64 Padding;0x338 // Alignment requirement
*/

GCC_ASM_EXPORT(ExceptionHandlersEnd)
Expand All @@ -99,7 +101,7 @@ GCC_ASM_EXPORT(CommonCExceptionHandler)

#define GP_CONTEXT_SIZE (32 * 8)
#define FP_CONTEXT_SIZE (32 * 16)
#define SYS_CONTEXT_SIZE ( 6 * 8) // 5 SYS regs + Alignment requirement (ie: the stack must be aligned on 0x10)
#define SYS_CONTEXT_SIZE ( 8 * 8) // 7 SYS regs + Alignment requirement (ie: the stack must be aligned on 0x10)

ASM_FUNC_ALIGN(ExceptionHandlerBase, 4096)

Expand Down Expand Up @@ -264,6 +266,11 @@ ASM_PFX(CommonExceptionEntry):
stp x2, x3, [x28, #-SYS_CONTEXT_SIZE]!
stp x4, x5, [x28, #0x10]
stp x6, x0, [x28, #0x20]
EL1_OR_EL2(x1)
1:mrs x2, ttbr0_el1
b 3f
2:mrs x2, ttbr0_el2
3:stp x2, xzr, [x28, #0x30]

// Push FP regs to Stack.
stp q0, q1, [x28, #-FP_CONTEXT_SIZE]!
Expand All @@ -288,17 +295,12 @@ ASM_PFX(CommonExceptionEntry):
cmp x2, 0 // Check whether EL0 process was interrupted
b.ne NoTTBR0Switch
adrp x1, ASM_PFX(CorePageTable)
ldr x4, [x1]
EL1_OR_EL2(x3)
1:mrs x4, ttbr0_el1
str x4, [x1, #0x8] // UserPageTable
ldr x4, [x1] // CorePageTable
msr ttbr0_el1, x4
1:msr ttbr0_el1, x4
tlbi vmalle1
b 3f
2:mrs x4, ttbr0_el2
str x4, [x1, #0x8] // UserPageTable
ldr x4, [x1] // CorePageTable
msr ttbr0_el2, x4
2:msr ttbr0_el2, x4
tlbi alle2
3:dsb sy
isb
Expand All @@ -324,14 +326,12 @@ NoTTBR0Switch:
and x2, x2, #0xF
cmp x2, 0 // Check whether EL0 process was interrupted
b.ne NoTTBR0Switch2
adrp x1, ASM_PFX(CorePageTable)
ldr x4, [x28, #(FP_CONTEXT_SIZE + 0x30)] // UserPageTable
EL1_OR_EL2(x3)
1:ldr x4, [x1, #0x8] // UserPageTable
msr ttbr0_el1, x4
1:msr ttbr0_el1, x4
tlbi vmalle1
b 3f
2:ldr x4, [x1, #0x8] // UserPageTable
msr ttbr0_el2, x4
2:msr ttbr0_el2, x4
tlbi alle2
3:dsb sy
isb
Expand Down Expand Up @@ -428,9 +428,6 @@ ASM_FUNC(RegisterEl0Stack)
ASM_PFX(CorePageTable):
.ds.d 1

UserPageTable:
.ds.d 1

.balign 4096
Padding:
.ds.b 1
51 changes: 29 additions & 22 deletions ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@ This is the stack constructed by the exception handler (low address to high addr

LR 0x54 # SVC Link register (we need to restore it)

LR 0x58 # pushed by srsfd
CPSR 0x5c
TTBR0 0x58
Padding 0x5c

LR 0x60 # pushed by srsfd
CPSR 0x64

*/

Expand Down Expand Up @@ -98,7 +101,7 @@ ASM_PFX(Fiq):
ASM_PFX(ResetEntry):
srsdb #0x13! @ Store return state on SVC stack
@ We are already in SVC mode

sub SP, SP, #0x8 @ Save space for TTBR0
stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state
Expand All @@ -111,6 +114,7 @@ ASM_PFX(UndefinedInstructionEntry):
sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0
stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state
Expand All @@ -124,6 +128,7 @@ ASM_PFX(SoftwareInterruptEntry):
isb
srsdb #0x13! @ Store return state on SVC stack
@ We are already in SVC mode
sub SP, SP, #0x8 @ Save space for TTBR0
stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state
Expand All @@ -136,6 +141,7 @@ ASM_PFX(PrefetchAbortEntry):
sub LR,LR,#4
srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0
stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state
Expand All @@ -148,6 +154,7 @@ ASM_PFX(DataAbortEntry):
sub LR,LR,#8
srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0
stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state
Expand All @@ -159,6 +166,7 @@ ASM_PFX(DataAbortEntry):
ASM_PFX(ReservedExceptionEntry):
srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0
stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state
Expand All @@ -171,6 +179,7 @@ ASM_PFX(IrqEntry):
sub LR,LR,#4
srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0
stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state
Expand All @@ -183,6 +192,7 @@ ASM_PFX(FiqEntry):
sub LR,LR,#4
srsdb #0x13! @ Store return state on SVC stack
cps #0x13 @ Switch to SVC for common stack
sub SP, SP, #0x8 @ Save space for TTBR0
stmfd SP!,{LR} @ Store the link register for the current mode
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
stmfd SP!,{R0-R12} @ Store the register state
Expand Down Expand Up @@ -217,7 +227,7 @@ ASM_PFX(AsmCommonExceptionEntry):
mrc p15, 0, R1, c5, c0, 0 @ Read DFSR
str R1, [SP, #0x44] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR

ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack
ldr R1, [SP, #0x64] @ srsdb saved pre-exception CPSR on the stack
str R1, [SP, #0x40] @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR

add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
Expand All @@ -229,20 +239,20 @@ ASM_PFX(AsmCommonExceptionEntry):
stmdaeq R2, {sp}^ @ save unbanked sp
@ else
stmdane R2, {lr} @ save SVC lr
addne R1, SP, #0x60 @ We pushed 0x60 bytes on the stack
addne R1, SP, #0x68 @ We pushed 0x68 bytes on the stack
strne R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP


ldr R5, [SP, #0x58] @ PC is the LR pushed by srsfd
ldr R5, [SP, #0x60] @ PC is the LR pushed by srsfd
@ Check to see if we have to adjust for Thumb entry
sub r4, r0, #1 @ if (ExceptionType == 1 || ExceptionType == 2)) {
cmp r4, #1 @ // UND & SVC have different LR adjust for Thumb
bhi NoAdjustNeeded

ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack
ldr R1, [SP, #0x64] @ srsdb saved pre-exception CPSR on the stack
tst r1, #0x20 @ if ((CPSR & T)) == T) { // Thumb Mode on entry
addne R5, R5, #2 @ PC += 2;
strne R5,[SP,#0x58] @ Update LR value pushed by srsfd
strne R5,[SP,#0x60] @ Update LR value pushed by srsfd

NoAdjustNeeded:

Expand All @@ -251,17 +261,12 @@ NoAdjustNeeded:
@ R0 is ExceptionType
mov R1,SP @ R1 is SystemContext

#if (FixedPcdGet32(PcdVFPEnabled))
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]
str R5, [SP, #0x58]
and R5, R5, #0x7F @ Preserve TTBR0 attributes
LDRL (R6, ASM_PFX(CorePageTable))
orr R6, R6, R5 @ Assign TTBR0 attributes
Expand All @@ -273,6 +278,10 @@ NoAdjustNeeded:

NoTTBR0Switch:

#if (FixedPcdGet32(PcdVFPEnabled))
vpush {d0-d15} @ save vstm registers in case they are used in optimizations
#endif

mov R4, SP @ Save current SP
tst R4, #4
subne SP, SP, #4 @ Adjust SP if not 8-byte aligned
Expand All @@ -292,11 +301,15 @@ CommonCExceptionHandler (

mov SP, R4 @ Restore SP

#if (FixedPcdGet32(PcdVFPEnabled))
vpop {d0-d15}
#endif

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)
ldr R4, [SP, #0x58] @ User Page Table
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.
Expand All @@ -305,10 +318,6 @@ CommonCExceptionHandler (

NoTTBR0Switch2:

#if (FixedPcdGet32(PcdVFPEnabled))
vpop {d0-d15}
#endif

ldr R1, [SP, #0x4c] @ Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
mcr p15, 0, R1, c5, c0, 1 @ Write IFSR

Expand All @@ -325,6 +334,7 @@ NoTTBR0Switch2:

add SP,SP,#0x20 @ Clear out the remaining stack space
ldmfd SP!,{LR} @ restore the link register for this context
add SP, SP, #0x8 @ Clear out TTBR0 and Padding
rfefd SP! @ return from exception via srsfd stack slot

ASM_FUNC_ALIGN(ExceptionHandlerFinal, 4096)
Expand All @@ -336,9 +346,6 @@ ASM_FUNC_ALIGN(ExceptionHandlerFinal, 4096)
ASM_PFX(CorePageTable):
.ds.l 1

UserPageTable:
.ds.l 1

.balign 4096
Padding:
.ds.b 1
2 changes: 1 addition & 1 deletion ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ APRIORI DXE {
INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
INF USER FatPkg/EnhancedFatDxe/Fat.inf
INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
INF USER MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf

Expand Down
6 changes: 4 additions & 2 deletions MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ ASM_FUNC(ArmCallRing3)
stp q12, q13, [sp, #0xa0]
stp q14, q15, [sp, #0x80]

stp xzr, x16, [sp, #0x70]
mrs x6, sp_el0
stp x6, x16, [sp, #0x70]
stp x17, x18, [sp, #0x60]
stp x19, x20, [sp, #0x50]
stp x21, x22, [sp, #0x40]
Expand Down Expand Up @@ -138,7 +139,7 @@ ASM_FUNC(ReturnToCore)
ldp q12, q13, [sp, #0xa0]
ldp q14, q15, [sp, #0x80]

ldr x16, [sp, #0x78]
ldp x6, x16, [sp, #0x70]
ldp x17, x18, [sp, #0x60]
ldp x19, x20, [sp, #0x50]
ldp x21, x22, [sp, #0x40]
Expand All @@ -147,6 +148,7 @@ ASM_FUNC(ReturnToCore)
ldp x27, x28, [sp, #0x10]
ldp x29, x30, [sp]
add sp, sp, #0x100
msr sp_el0, x6
// Enable interrupts.
msr daifclr, #0xf
isb
Expand Down
5 changes: 1 addition & 4 deletions MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@

#include "DxeMain.h"

STATIC UINTN mSysCallStackTop;
UINTN gUserPageTable;
UINTN gUserPageTable;

EFI_STATUS
EFIAPI
Expand Down Expand Up @@ -156,8 +155,6 @@ CallRing3 (
IN UINTN *ReturnSP
)
{
mSysCallStackTop = SysCallStackTop;

return ArmCallRing3 (
Data,
UserStackTop,
Expand Down
7 changes: 7 additions & 0 deletions MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ ASM_FUNC(ArmCallRing3)
ldr R6, [SP, #0x28]
// R7 is gUserPageTable
ldr R7, [SP, #0x2C]
// Save old SP_usr and LR_usr on Core Stack.
sub SP, SP, #0x8
stmia SP, {SP, LR}^

#if (FixedPcdGet32(PcdVFPEnabled))
// Save vstm registers in case they are used in optimizations.
Expand Down Expand Up @@ -135,6 +138,10 @@ ASM_FUNC(ReturnToCore)
vpop {d0-d15}
#endif

// Restore old SP_usr and LR_usr.
ldmia SP, {SP, LR}^
add SP, SP, #0x8

pop {R4-R12, LR}

// Enable interrupts.
Expand Down
5 changes: 1 addition & 4 deletions MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@

#include "DxeMain.h"

STATIC UINTN mSysCallStackTop;
UINTN gUserPageTable;
UINTN gUserPageTable;

EFI_STATUS
EFIAPI
Expand Down Expand Up @@ -151,8 +150,6 @@ CallRing3 (
IN UINTN *ReturnSP
)
{
mSysCallStackTop = SysCallStackTop;

return ArmCallRing3 (
Data,
UserStackTop,
Expand Down
Loading

0 comments on commit 93625d5

Please sign in to comment.