Skip to content

Commit 0fdae43

Browse files
committed
Build: Switch to BaseMemoryLibRepStr for optimised memory routines
We cannot use BaseMemoryLibOptDxe since it uses SSE instructions, and some firmwares fail to properly maintain MMX register contexts across the timers. This results in exceptions when trying to execute primitives like CopyMem in timers (e.g. AIKDataWriteEntry). Reproduced on ASUS M5A97 with AMD FX8320 CPU. closes acidanthera/bugtracker#754
1 parent ae5e1f4 commit 0fdae43

File tree

6 files changed

+166
-4
lines changed

6 files changed

+166
-4
lines changed
+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/** @file
2+
Check memory routine compatibility.
3+
4+
Copyright (c) 2018, vit9696. All rights reserved.<BR>
5+
This program and the accompanying materials
6+
are licensed and made available under the terms and conditions of the BSD License
7+
which accompanies this distribution. The full text of the license may be found at
8+
http://opensource.org/licenses/bsd-license.php
9+
10+
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12+
13+
**/
14+
15+
#include <Uefi.h>
16+
#include <Library/BaseMemoryLib.h>
17+
#include <Library/BaseLib.h>
18+
#include <Library/DebugLib.h>
19+
#include <Library/OcMiscLib.h>
20+
#include <Library/UefiLib.h>
21+
#include <Library/UefiBootServicesTableLib.h>
22+
23+
STATIC UINT8 mSource[64];
24+
STATIC UINT8 mDestination[64];
25+
26+
EFI_STATUS
27+
EFIAPI
28+
UefiMain (
29+
IN EFI_HANDLE ImageHandle,
30+
IN EFI_SYSTEM_TABLE *SystemTable
31+
)
32+
{
33+
UINT8 *Src;
34+
UINT8 *Dst;
35+
UINT32 Size;
36+
IA32_CR0 Cr0;
37+
IA32_CR4 Cr4;
38+
IA32_EFLAGS32 Flags;
39+
40+
Src = ALIGN_POINTER (mSource, 16);
41+
Dst = ALIGN_POINTER (mDestination, 16);
42+
Size = 32;
43+
44+
gST->ConOut->OutputString (gST->ConOut, L"VerifyMemOpt\r\n");
45+
gBS->Stall (SECONDS_TO_MICROSECONDS (1));
46+
47+
Cr0.UintN = AsmReadCr0 ();
48+
Cr4.UintN = AsmReadCr4 ();
49+
Flags.UintN = AsmReadEflags();
50+
51+
//
52+
// CR0.MP bit (BIT1) must be set.
53+
// CR0.EM bit (BIT2) must be cleared.
54+
// CR4.OSFXSR bit (BIT9) must be set.
55+
// CR4.OSXMMEXCPT bit (BIT10) must be set.
56+
//
57+
DEBUG ((DEBUG_WARN, "VMOPT: CR0 %08X CR4 %08X EFLAGS %08X\n", Cr0, Cr4, Flags));
58+
59+
if (Cr0.Bits.MP == 0) {
60+
DEBUG ((DEBUG_WARN, "VMOPT: WARN CR0 MP is NOT set\n"));
61+
}
62+
63+
if (Cr0.Bits.EM != 0) {
64+
DEBUG ((DEBUG_WARN, "VMOPT: WARN CR0 EM is set\n"));
65+
}
66+
67+
if (Cr4.Bits.OSFXSR == 0) {
68+
DEBUG ((DEBUG_WARN, "VMOPT: WARN CR4 OSFXSR is NOT set\n"));
69+
}
70+
71+
if (Cr4.Bits.OSXMMEXCPT == 0) {
72+
DEBUG ((DEBUG_WARN, "VMOPT: WARN CR4 OSXMMEXCPT is NOT set\n"));
73+
}
74+
75+
if (Flags.Bits.DF != 0) {
76+
DEBUG ((DEBUG_WARN, "VMOPT: WARN EFLAGS DF is set\n"));
77+
}
78+
79+
DEBUG ((DEBUG_WARN, "VMOPT: CopyMem aligned src %p/aligned dst %p/size %u\n", Src, Dst, Size));
80+
gBS->Stall (SECONDS_TO_MICROSECONDS (1));
81+
CopyMem (Dst, Src, Size);
82+
83+
Src += 6;
84+
DEBUG ((DEBUG_WARN, "VMOPT: CopyMem unaligned src %p/aligned dst %p/size %u\n", Src, Dst, Size));
85+
gBS->Stall (SECONDS_TO_MICROSECONDS (1));
86+
CopyMem (Dst, Src, Size);
87+
88+
Size -= 12;
89+
DEBUG ((DEBUG_WARN, "VMOPT: CopyMem unaligned src %p/aligned dst %p/size %u\n", Src, Dst, Size));
90+
gBS->Stall (SECONDS_TO_MICROSECONDS (1));
91+
CopyMem (Dst, Src, Size);
92+
93+
Dst += 6;
94+
DEBUG ((DEBUG_WARN, "VMOPT: CopyMem unaligned src %p/unaligned dst %p/size %u\n", Src, Dst, Size));
95+
gBS->Stall (SECONDS_TO_MICROSECONDS (1));
96+
CopyMem (Dst, Src, Size);
97+
98+
DEBUG ((DEBUG_WARN, "VMOPT: Done testing\n"));
99+
gBS->Stall (SECONDS_TO_MICROSECONDS (1));
100+
101+
return EFI_SUCCESS;
102+
}
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
## @file
2+
# Check memory routine compatibility.
3+
#
4+
# Copyright (c) 2018, vit9696. All rights reserved.<BR>
5+
#
6+
# This program and the accompanying materials
7+
# are licensed and made available under the terms and conditions of the BSD License
8+
# which accompanies this distribution. The full text of the license may be found at
9+
# http://opensource.org/licenses/bsd-license.php
10+
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12+
#
13+
##
14+
15+
[Defines]
16+
INF_VERSION = 0x00010005
17+
BASE_NAME = VerifyMemOpt
18+
FILE_GUID = 00697824-B09E-43D6-8A2A-1CD9E5C7BFBC
19+
MODULE_TYPE = UEFI_APPLICATION
20+
VERSION_STRING = 1.0
21+
ENTRY_POINT = UefiMain
22+
23+
#
24+
# This flag specifies whether HII resource section is generated into PE image.
25+
#
26+
UEFI_HII_RESOURCE_SECTION = TRUE
27+
28+
#
29+
# The following information is for reference only and not required by the build tools.
30+
#
31+
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
32+
#
33+
34+
[Sources]
35+
VerifyMemOpt.c
36+
37+
[Packages]
38+
MdePkg/MdePkg.dec
39+
MdeModulePkg/MdeModulePkg.dec
40+
OpenCorePkg/OpenCorePkg.dec
41+
UefiCpuPkg/UefiCpuPkg.dec
42+
43+
[LibraryClasses]
44+
OcConsoleControlEntryModeGenericLib
45+
UefiApplicationEntryPoint
46+
UefiLib
47+
PcdLib
48+
IoLib

Changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ OpenCore Changelog
4444
- Added prebuilt version of `CrScreenshotDxe` driver
4545
- Fixed Hyper-V frequency detection compatibility
4646
- Added `SysReport` option for DEBUG builds to dump system info
47+
- Fixed crashes on some AMD firmwares when performing keyboard input
4748

4849
#### v0.5.8
4950
- Fixed invalid CPU object reference in SSDT-PLUG

Docs/Configuration.tex

+1
Original file line numberDiff line numberDiff line change
@@ -2722,6 +2722,7 @@ \subsection{Debug Properties}\label{miscdebugprops}
27222722
\item \texttt{OCRST} --- ResetSystem
27232723
\item \texttt{OCUI} --- OpenCanopy
27242724
\item \texttt{OC} --- OpenCore main
2725+
\item \texttt{VMOPT} --- VerifyMemOpt
27252726
\end{itemize}
27262727

27272728
\textbf{Libraries}:

OpenCorePkg.dsc

+13-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,13 @@
2525

2626
[LibraryClasses]
2727
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
28-
BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
28+
# We cannot use BaseMemoryLibOptDxe since it uses SSE instructions,
29+
# and some firmwares fail to properly maintain MMX register contexts
30+
# across the timers. This results in exceptions when trying to execute
31+
# primitives like CopyMem in timers (e.g. AIKDataWriteEntry).
32+
# Reproduced on ASUS M5A97 with AMD FX8320 CPU.
33+
# REF: https://github.com/acidanthera/bugtracker/issues/754
34+
BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
2935
BaseRngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
3036
BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
3137
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
@@ -127,13 +133,13 @@
127133
!include NetworkPkg/NetworkLibs.dsc.inc
128134

129135
[Components]
130-
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf{
136+
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf {
131137
<LibraryClasses>
132138
!if $(TARGET) == RELEASE
133139
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
134140
!endif
135141
}
136-
MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf{
142+
MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf {
137143
<LibraryClasses>
138144
!if $(TARGET) == RELEASE
139145
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
@@ -155,6 +161,10 @@
155161
OpenCorePkg/Application/PavpProvision/PavpProvision.inf
156162
OpenCorePkg/Application/ResetSystem/ResetSystem.inf
157163
OpenCorePkg/Application/RtcRw/RtcRw.inf
164+
OpenCorePkg/Application/VerifyMemOpt/VerifyMemOpt.inf {
165+
<LibraryClasses>
166+
BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
167+
}
158168
OpenCorePkg/Application/VerifyMsrE2/VerifyMsrE2.inf
159169
OpenCorePkg/Debug/GdbSyms/GdbSyms.inf
160170
OpenCorePkg/Library/OcAcpiLib/OcAcpiLib.inf

OpenDuetPkg.dsc

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
#
4040
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
4141
!if $(ARCH) == X64
42-
BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
42+
BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
4343
!else
4444
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
4545
!endif

0 commit comments

Comments
 (0)