OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
OpenCoreUefiInOut.c
Go to the documentation of this file.
1
15#include <Library/OcMainLib.h>
16
17#include <Guid/OcVariable.h>
18#include <Guid/GlobalVariable.h>
19#include <Guid/AppleVariable.h>
20
21#include <Library/BaseLib.h>
22#include <Library/DebugLib.h>
23#include <Library/DevicePathLib.h>
24#include <Library/MemoryAllocationLib.h>
25#include <Library/MtrrLib.h>
30#include <Library/OcAudioLib.h>
31#include <Library/OcInputLib.h>
35#include <Library/OcCpuLib.h>
41#include <Library/OcMiscLib.h>
42#include <Library/OcSmcLib.h>
43#include <Library/OcOSInfoLib.h>
45#include <Library/PrintLib.h>
46#include <Library/UefiBootServicesTableLib.h>
47#include <Library/UefiLib.h>
48#include <Library/UefiRuntimeServicesTableLib.h>
49
50STATIC
51VOID
52EFIAPI
54 IN EFI_EVENT Event,
55 IN VOID *Context
56 )
57{
58 EFI_STATUS Status;
59 OC_GLOBAL_CONFIG *Config;
60
61 Config = Context;
62
63 //
64 // Printing from ExitBootServices is dangerous, as it may cause
65 // memory reallocation, which can make ExitBootServices fail.
66 // Only do that on error, which is not expected.
67 //
68
69 if (Config->Uefi.Input.TimerResolution != 0) {
71 if (EFI_ERROR (Status)) {
72 DEBUG ((
73 DEBUG_INFO,
74 "OC: OcAppleGenericInputTimerQuirkExit status - %r\n",
75 Status
76 ));
77 }
78 }
79
80 if (Config->Uefi.Input.PointerSupport) {
82 if (EFI_ERROR (Status)) {
83 DEBUG ((
84 DEBUG_INFO,
85 "OC: OcAppleGenericInputPointerExit status - %r\n",
86 Status
87 ));
88 }
89 }
90
91 if (Config->Uefi.Input.KeySupport) {
93 if (EFI_ERROR (Status)) {
94 DEBUG ((
95 DEBUG_INFO,
96 "OC: OcAppleGenericInputKeycodeExit status - %r\n",
97 Status
98 ));
99 }
100 }
101}
102
103VOID
105 IN OC_GLOBAL_CONFIG *Config
106 )
107{
108 BOOLEAN ExitBs;
109 EFI_STATUS Status;
110 UINT32 TimerResolution;
111 CONST CHAR8 *PointerSupportStr;
112 OC_INPUT_POINTER_MODE PointerMode;
113 OC_INPUT_KEY_MODE KeyMode;
114 CONST CHAR8 *KeySupportStr;
115
116 ExitBs = FALSE;
117
118 TimerResolution = Config->Uefi.Input.TimerResolution;
119 if (TimerResolution != 0) {
120 Status = OcAppleGenericInputTimerQuirkInit (TimerResolution);
121 if (EFI_ERROR (Status)) {
122 DEBUG ((DEBUG_ERROR, "OC: Failed to initialize timer quirk\n"));
123 } else {
124 ExitBs = TRUE;
125 }
126 }
127
128 if (Config->Uefi.Input.PointerSupport) {
129 PointerSupportStr = OC_BLOB_GET (&Config->Uefi.Input.PointerSupportMode);
130 PointerMode = OcInputPointerModeMax;
131 if (AsciiStrCmp (PointerSupportStr, "ASUS") == 0) {
132 PointerMode = OcInputPointerModeAsus;
133 } else {
134 DEBUG ((DEBUG_WARN, "OC: Invalid input pointer mode %a\n", PointerSupportStr));
135 }
136
137 if (PointerMode != OcInputPointerModeMax) {
138 Status = OcAppleGenericInputPointerInit (PointerMode);
139 if (EFI_ERROR (Status)) {
140 DEBUG ((DEBUG_INFO, "OC: Failed to initialize pointer\n"));
141 } else {
142 ExitBs = TRUE;
143 }
144 }
145 }
146
147 if (Config->Uefi.Input.KeySupport) {
148 DEBUG ((DEBUG_INFO, "OC: Installing KeySupport...\n"));
149 KeySupportStr = OC_BLOB_GET (&Config->Uefi.Input.KeySupportMode);
150 KeyMode = OcInputKeyModeMax;
151 if (AsciiStrCmp (KeySupportStr, "Auto") == 0) {
152 KeyMode = OcInputKeyModeAuto;
153 } else if (AsciiStrCmp (KeySupportStr, "V1") == 0) {
154 KeyMode = OcInputKeyModeV1;
155 } else if (AsciiStrCmp (KeySupportStr, "V2") == 0) {
156 KeyMode = OcInputKeyModeV2;
157 } else if (AsciiStrCmp (KeySupportStr, "AMI") == 0) {
158 KeyMode = OcInputKeyModeAmi;
159 } else {
160 DEBUG ((DEBUG_WARN, "OC: Invalid input key mode %a\n", KeySupportStr));
161 }
162
163 if (KeyMode != OcInputKeyModeMax) {
165 KeyMode,
166 Config->Uefi.Input.KeyForgetThreshold,
167 Config->Uefi.Input.KeySwap,
168 Config->Uefi.Input.KeyFiltering
169 );
170 if (EFI_ERROR (Status)) {
171 DEBUG ((DEBUG_ERROR, "OC: Failed to initialize keycode\n"));
172 } else {
173 ExitBs = TRUE;
174 }
175 }
176 }
177
178 if (ExitBs) {
180 }
181}
182
183VOID
185 IN OC_STORAGE_CONTEXT *Storage,
186 IN OC_GLOBAL_CONFIG *Config
187 )
188{
189 EFI_STATUS Status;
190 CONST CHAR8 *AsciiMode;
191 CONST CHAR8 *AsciiRenderer;
192 CONST CHAR8 *GopPassThrough;
193 EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
195 OC_CONSOLE_RENDERER Renderer;
196 UINT32 Width;
197 UINT32 Height;
198 UINT32 Bpp;
199 BOOLEAN SetMax;
200 UINT8 UIScale;
201
202 GopPassThrough = OC_BLOB_GET (&Config->Uefi.Output.GopPassThrough);
203 if (AsciiStrCmp (GopPassThrough, "Enabled") == 0) {
204 Status = OcProvideGopPassThrough (TRUE);
205 } else if (AsciiStrCmp (GopPassThrough, "Apple") == 0) {
206 Status = OcProvideGopPassThrough (FALSE);
207 } else {
208 Status = EFI_SUCCESS;
209 }
210
211 if (EFI_ERROR (Status)) {
212 DEBUG ((
213 DEBUG_INFO,
214 "OC: OcProvideGopPassThrough %a status - %r\n",
215 GopPassThrough,
216 Status
217 ));
218 }
219
220 if (Config->Uefi.Output.ProvideConsoleGop) {
221 OcProvideConsoleGop (TRUE);
222 }
223
225 OC_BLOB_GET (&Config->Uefi.Output.Resolution),
226 &Width,
227 &Height,
228 &Bpp,
229 &SetMax
230 );
231
232 DEBUG ((
233 DEBUG_INFO,
234 "OC: Requested resolution is %ux%u@%u (max: %d, force: %d) from %a\n",
235 Width,
236 Height,
237 Bpp,
238 SetMax,
239 Config->Uefi.Output.ForceResolution,
240 OC_BLOB_GET (&Config->Uefi.Output.Resolution)
241 ));
242
243 if (SetMax || ((Width > 0) && (Height > 0))) {
244 Status = OcSetConsoleResolution (
245 Width,
246 Height,
247 Bpp,
248 Config->Uefi.Output.ForceResolution
249 );
250 DEBUG ((
251 EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED ? DEBUG_WARN : DEBUG_INFO,
252 "OC: Changed resolution to %ux%u@%u (max: %d, force: %d) from %a - %r\n",
253 Width,
254 Height,
255 Bpp,
256 SetMax,
257 Config->Uefi.Output.ForceResolution,
258 OC_BLOB_GET (&Config->Uefi.Output.Resolution),
259 Status
260 ));
261 } else {
262 Status = EFI_UNSUPPORTED;
263 }
264
265 if (Config->Uefi.Output.GopBurstMode) {
267 }
268
269 if (Config->Uefi.Output.DirectGopRendering) {
270 OcUseDirectGop (-1);
271 }
272
273 if (Config->Uefi.Output.ReconnectOnResChange && !EFI_ERROR (Status)) {
275 }
276
277 if (Config->Uefi.Output.UgaPassThrough) {
278 Status = OcProvideUgaPassThrough ();
279 if (EFI_ERROR (Status)) {
280 DEBUG ((
281 DEBUG_INFO,
282 "OC: OcProvideUgaPassThrough status - %r\n",
283 Status
284 ));
285 }
286 }
287
288 if ((Config->Uefi.Output.UIScale >= 0) && (Config->Uefi.Output.UIScale <= 2)) {
289 if (Config->Uefi.Output.UIScale == 0) {
290 Status = gBS->HandleProtocol (
291 gST->ConsoleOutHandle,
293 (VOID **)&Gop
294 );
295 if (!EFI_ERROR (Status)) {
296 UIScale = (UINT64)Gop->Mode->Info->HorizontalResolution
297 * Gop->Mode->Info->VerticalResolution >= 4000000 ? 2 : 1;
298 DEBUG ((
299 DEBUG_INFO,
300 "OC: Selected UIScale %d based on %ux%u resolution\n",
301 UIScale,
302 Gop->Mode->Info->HorizontalResolution,
303 Gop->Mode->Info->VerticalResolution
304 ));
305 } else {
306 UIScale = 1;
307 }
308 } else {
309 UIScale = (UINT8)Config->Uefi.Output.UIScale;
310 }
311
312 Status = OcSetSystemVariable (
314 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
315 sizeof (UIScale),
316 &UIScale,
318 );
319 DEBUG ((DEBUG_INFO, "OC: Setting UIScale to %d - %r\n", UIScale, Status));
320 }
321
322 AsciiMode = OC_BLOB_GET (&Config->Uefi.Output.InitialMode);
323
324 if ((AsciiMode[0] == '\0') || (AsciiStrCmp (AsciiMode, "Auto") == 0)) {
326 } else if (AsciiStrCmp (AsciiMode, "Text") == 0) {
327 InitialMode = EfiConsoleControlScreenText;
328 } else if (AsciiStrCmp (AsciiMode, "Graphics") == 0) {
330 } else {
331 DEBUG ((DEBUG_WARN, "OC: Requested unknown initial mode %a\n", AsciiMode));
333 }
334
335 AsciiRenderer = OC_BLOB_GET (&Config->Uefi.Output.TextRenderer);
336
337 if ((AsciiRenderer[0] == '\0') || (AsciiStrCmp (AsciiRenderer, "BuiltinGraphics") == 0)) {
339 } else if (AsciiStrCmp (AsciiRenderer, "BuiltinText") == 0) {
341 } else if (AsciiStrCmp (AsciiRenderer, "SystemGraphics") == 0) {
343 } else if (AsciiStrCmp (AsciiRenderer, "SystemText") == 0) {
345 } else if (AsciiStrCmp (AsciiRenderer, "SystemGeneric") == 0) {
347 } else {
348 DEBUG ((DEBUG_WARN, "OC: Requested unknown renderer %a\n", AsciiRenderer));
350 }
351
353 OC_BLOB_GET (&Config->Uefi.Output.ConsoleMode),
354 &Width,
355 &Height,
356 &SetMax
357 );
358
360 InitialMode,
361 Renderer,
362 Storage,
363 OC_BLOB_GET (&Config->Uefi.Output.ConsoleFont),
364 Config->Uefi.Output.IgnoreTextInGraphics,
365 Config->Uefi.Output.SanitiseClearScreen,
366 Config->Uefi.Output.ClearScreenOnModeSwitch,
367 Config->Uefi.Output.ReplaceTabWithSpace,
368 Width,
369 Height
370 );
371
372 DEBUG ((
373 DEBUG_INFO,
374 "OC: Requested console mode is %ux%u (max: %d) from %a\n",
375 Width,
376 Height,
377 SetMax,
378 OC_BLOB_GET (&Config->Uefi.Output.ConsoleMode)
379 ));
380
381 if (SetMax || ((Width > 0) && (Height > 0))) {
382 Status = OcSetConsoleMode (Width, Height);
383 DEBUG ((
384 EFI_ERROR (Status) ? DEBUG_WARN : DEBUG_INFO,
385 "OC: Changed console mode to %ux%u (max: %d) from %a - %r\n",
386 Width,
387 Height,
388 SetMax,
389 OC_BLOB_GET (&Config->Uefi.Output.ConsoleMode),
390 Status
391 ));
392 }
393}
EFI_GUID gAppleVendorVariableGuid
#define APPLE_UI_SCALE_VARIABLE_NAME
EFI_CONSOLE_CONTROL_SCREEN_MODE
@ EfiConsoleControlScreenGraphics
@ EfiConsoleControlScreenMaxValue
@ EfiConsoleControlScreenText
EFI_SYSTEM_TABLE * gST
EFI_BOOT_SERVICES * gBS
EFI_STATUS OcSetGopBurstMode(VOID)
Definition GopUtils.c:308
EFI_STATUS OcSetConsoleResolution(IN UINT32 Width OPTIONAL, IN UINT32 Height OPTIONAL, IN UINT32 Bpp OPTIONAL, IN BOOLEAN Force)
EFI_STATUS OcUseDirectGop(IN INT32 CacheType)
Definition ConsoleGop.c:536
VOID OcParseScreenResolution(IN CONST CHAR8 *String, OUT UINT32 *Width, OUT UINT32 *Height, OUT UINT32 *Bpp, OUT BOOLEAN *Max)
VOID OcSetupConsole(IN EFI_CONSOLE_CONTROL_SCREEN_MODE InitialMode, IN OC_CONSOLE_RENDERER Renderer, IN OC_STORAGE_CONTEXT *Storage OPTIONAL, IN CONST CHAR8 *Font OPTIONAL, IN BOOLEAN IgnoreTextOutput, IN BOOLEAN SanitiseClearScreen, IN BOOLEAN ClearScreenOnModeSwitch, IN BOOLEAN ReplaceTabWithSpace, IN UINT32 Width, IN UINT32 Height)
OC_CONSOLE_RENDERER
@ OcConsoleRendererSystemGraphics
@ OcConsoleRendererBuiltinText
@ OcConsoleRendererSystemGeneric
@ OcConsoleRendererSystemText
@ OcConsoleRendererBuiltinGraphics
EFI_STATUS OcProvideConsoleGop(IN BOOLEAN Route)
Definition ConsoleGop.c:81
VOID OcParseConsoleMode(IN CONST CHAR8 *String, OUT UINT32 *Width, OUT UINT32 *Height, OUT BOOLEAN *Max)
EFI_STATUS OcProvideGopPassThrough(IN BOOLEAN ForAll)
VOID OcReconnectConsole(VOID)
Definition ConsoleGop.c:482
EFI_STATUS OcSetConsoleMode(IN UINT32 Width, IN UINT32 Height)
EFI_STATUS OcProvideUgaPassThrough(VOID)
OC_INPUT_KEY_MODE
Definition OcInputLib.h:23
@ OcInputKeyModeMax
Definition OcInputLib.h:28
@ OcInputKeyModeV1
Definition OcInputLib.h:25
@ OcInputKeyModeV2
Definition OcInputLib.h:26
@ OcInputKeyModeAuto
Definition OcInputLib.h:24
@ OcInputKeyModeAmi
Definition OcInputLib.h:27
EFI_STATUS OcAppleGenericInputPointerExit(VOID)
Definition AIM.c:596
EFI_STATUS OcAppleGenericInputKeycodeInit(IN OC_INPUT_KEY_MODE Mode, IN UINT8 KeyForgotThreshold, IN BOOLEAN KeySwap, IN BOOLEAN KeyFiltering)
Definition AIK.c:246
EFI_STATUS OcAppleGenericInputTimerQuirkExit(VOID)
Definition AIT.c:73
EFI_STATUS OcAppleGenericInputTimerQuirkInit(IN UINT32 TimerResolution)
Definition AIT.c:26
EFI_STATUS OcAppleGenericInputPointerInit(IN OC_INPUT_POINTER_MODE Mode)
Definition AIM.c:564
EFI_STATUS OcAppleGenericInputKeycodeExit(VOID)
Definition AIK.c:283
OC_INPUT_POINTER_MODE
Definition OcInputLib.h:18
@ OcInputPointerModeAsus
Definition OcInputLib.h:19
@ OcInputPointerModeMax
Definition OcInputLib.h:20
VOID OcScheduleExitBootServices(IN EFI_EVENT_NOTIFY Handler, IN VOID *Context)
#define OC_BLOB_GET(Blob)
EFI_STATUS OcSetSystemVariable(IN CHAR16 *VariableName, IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data, IN EFI_GUID *VendorGuid OPTIONAL)
VOID OcLoadUefiInputSupport(IN OC_GLOBAL_CONFIG *Config)
STATIC VOID EFIAPI OcExitBootServicesInputHandler(IN EFI_EVENT Event, IN VOID *Context)
VOID OcLoadUefiOutputSupport(IN OC_STORAGE_CONTEXT *Storage, IN OC_GLOBAL_CONFIG *Config)
EFI_GUID gEfiGraphicsOutputProtocolGuid