From 7807e5a5e14f3b98974a99f053d3d784abd5f1eb Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 30 May 2024 17:30:32 +0300 Subject: [PATCH] Ring3: Summarized all known problems for AARCH64. --- FatPkg/EnhancedFatDxe/Init.c | 2 +- FatPkg/EnhancedFatDxe/Open.c | 2 +- MdeModulePkg/Core/Dxe/DxeMain.inf | 3 +- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 5 ++ .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 68 ++++++++++++++++++- .../Core/Dxe/SysCall/Initialization.c | 8 ++- .../Core/Dxe/SysCall/SupportedProtocols.c | 29 +++++++- 7 files changed, 109 insertions(+), 8 deletions(-) diff --git a/FatPkg/EnhancedFatDxe/Init.c b/FatPkg/EnhancedFatDxe/Init.c index feae369693..f3bca7a7e8 100644 --- a/FatPkg/EnhancedFatDxe/Init.c +++ b/FatPkg/EnhancedFatDxe/Init.c @@ -93,7 +93,7 @@ FatAllocateVolume ( // // Volume installed // - DEBUG ((DEBUG_INIT, "Installed Fat filesystem on %p\n", Handle)); + // DEBUG ((DEBUG_INIT, "Installed Fat filesystem on %p\n", Handle)); Volume->Valid = TRUE; Done: diff --git a/FatPkg/EnhancedFatDxe/Open.c b/FatPkg/EnhancedFatDxe/Open.c index 32a8e59fa6..1dfe7b8f0e 100644 --- a/FatPkg/EnhancedFatDxe/Open.c +++ b/FatPkg/EnhancedFatDxe/Open.c @@ -172,7 +172,7 @@ FatOFileOpen ( (*NewIFile)->ReadOnly = (BOOLEAN) !WriteMode; - DEBUG ((DEBUG_INFO, "FSOpen: Open '%S' %r\n", FileName, Status)); + // DEBUG ((DEBUG_INFO, "FSOpen: Open '%S' %r\n", FileName, Status)); return FatOFileFlush (OFile); } diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 95eca8341b..c464b252a1 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -92,7 +92,8 @@ UefiCpuPkg/UefiCpuPkg.dec OvmfPkg/OvmfPkg.dec ArmPkg/ArmPkg.dec - + ArmVirtPkg/ArmVirtPkg.dec + [LibraryClasses] BaseMemoryLib CacheMaintenanceLib diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 068db95b1d..55d927bb30 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -129,6 +129,9 @@ ASM_FUNC(ReturnToCore) //------------------------------------------------------------------------------ ASM_FUNC(ArmSetPan) msr pan, #1 + // Problem 3: Nevertheless TLB invalidation is ignored by QEMU. + dsb sy + isb ret //------------------------------------------------------------------------------ @@ -140,4 +143,6 @@ ASM_FUNC(ArmSetPan) //------------------------------------------------------------------------------ ASM_FUNC(ArmClearPan) msr pan, #0 + dsb sy + isb ret diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index 88b06ac53a..ab2f1b536b 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -6,12 +6,14 @@ **/ #include +#include #include #include #include "DxeMain.h" STATIC UINTN mCoreSp; +UINTN gUartBaseAddress; EFI_STATUS EFIAPI @@ -70,6 +72,12 @@ SysCallBootService ( DisableSMAP (); CopyMem ((VOID *)((UINTN)Physical + sizeof (UINTN)), (VOID *)UserRsp, 8 * sizeof (UINTN)); + + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP + ); EnableSMAP (); Status = CallBootService ( @@ -78,6 +86,12 @@ SysCallBootService ( (RING3_STACK *)(UINTN)Physical ); + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); return Status; @@ -86,10 +100,17 @@ SysCallBootService ( VOID EFIAPI InitializeMsr ( - VOID + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries ) { - UINTN Tcr; + UINTN Tcr; + UINTN Index; + EARLY_PL011_BASE_ADDRESS *UartBase; + EFI_PHYSICAL_ADDRESS Physical; + EFI_HOB_GENERIC_HEADER *Ring3Hob; + UINT16 HobLength; + EFI_STATUS Status; // // If HCR_EL2.NV is 1 and the current Exception level is EL1, // then EL1 read accesses to the CurrentEL register return a value of 0x2 in bits[3:2]. @@ -103,6 +124,49 @@ InitializeMsr ( Tcr = ArmGetTCR (); Tcr |= TCR_EL1_HPD0_MASK | TCR_EL1_HPD1_MASK; ArmSetTCR (Tcr); + // + // Problem 1: Uart is memory maped. + // + for (Index = 0; Index < NumberOfEntries; ++Index) { + if (CompareGuid (&gEfiHobListGuid, &(Table[Index].VendorGuid))) { + UartBase = GET_GUID_HOB_DATA (Table[Index].VendorTable); + gUartBaseAddress = UartBase->DebugAddress; + // + // Copy Hob into Ring3. + // + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + 1, + &Physical + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Hob.\n")); + ASSERT (FALSE); + } + DEBUG ((DEBUG_ERROR, "UartBaseAddress = %p.\n", gUartBaseAddress)); + + Ring3Hob = (EFI_HOB_GENERIC_HEADER *)(UINTN)Physical; + + HobLength = (UINT16)((sizeof (EFI_HOB_GUID_TYPE) + sizeof (EARLY_PL011_BASE_ADDRESS) + 0x7) & (~0x7)); + + Ring3Hob->HobType = EFI_HOB_TYPE_GUID_EXTENSION; + Ring3Hob->HobLength = HobLength; + Ring3Hob->Reserved = 0; + + CopyGuid (&((EFI_HOB_GUID_TYPE *)Ring3Hob)->Name, &gEarlyPL011BaseAddressGuid); + + Ring3Hob = (EFI_HOB_GENERIC_HEADER *)((UINTN)Ring3Hob + HobLength); + + Ring3Hob->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; + Ring3Hob->HobLength = sizeof (EFI_HOB_GENERIC_HEADER); + Ring3Hob->Reserved = 0; + + Table[Index].VendorTable = (VOID *)(UINTN)Physical; + UartBase = GET_GUID_HOB_DATA (Table[Index].VendorTable); + UartBase->DebugAddress = gUartBaseAddress; + } + } if (ArmHasPan ()) { // diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 58651a4963..facc9d543d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -18,7 +18,8 @@ VOID *gRing3Interfaces; VOID EFIAPI InitializeMsr ( - VOID + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries ); EFI_STATUS @@ -141,7 +142,10 @@ InitializeRing3 ( SetUefiImageMemoryAttributes ((UINTN)gRing3CallStackBase, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop)); - InitializeMsr (); + InitializeMsr ( + gRing3Data->SystemTable.ConfigurationTable, + gRing3Data->SystemTable.NumberOfTableEntries + ); return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 90fd9761a1..5692a26ad6 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -13,6 +13,10 @@ EFI_FILE_PROTOCOL mRing3FileProtocol; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; +#if defined (MDE_CPU_AARCH64) +extern UINTN gUartBaseAddress; +#endif + typedef struct { EFI_FILE_PROTOCOL Protocol; EFI_FILE_PROTOCOL *Ring3File; @@ -69,8 +73,16 @@ GoToRing3 ( EFI_MEMORY_XP | EFI_MEMORY_USER ); } +#elif defined (MDE_CPU_AARCH64) + // + // Necessary fix for DEBUG printings. + // + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); #endif - Status = CallRing3 (Input); #if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) @@ -81,6 +93,21 @@ GoToRing3 ( EFI_MEMORY_XP ); } +#elif defined (MDE_CPU_AARCH64) + // + // Problem 2: Uart memory maped page is not allocated at the very beginnig + // and can be used for translation table later. + // + DisableSMAP (); + // + // Problem 4: QEMU ramdomly breaks GP registers' context. + // + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP + ); + EnableSMAP (); #endif CoreFreePages (Ring3Pages, PagesNumber);