OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
ForgeUefi.c
Go to the documentation of this file.
1
16#include <PiDxe.h>
17
18#include <Guid/EventGroup.h>
19
20#include <Library/BaseLib.h>
21#include <Library/BaseMemoryLib.h>
22#include <Library/DebugLib.h>
23#include <Library/DxeServicesTableLib.h>
24#include <Library/IoLib.h>
25#include <Library/MemoryAllocationLib.h>
27#include <Library/UefiBootServicesTableLib.h>
28
29STATIC
30EFI_STATUS
31EFIAPI
33 IN UINT32 Type,
34 IN EFI_TPL NotifyTpl,
35 IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL,
36 IN CONST VOID *NotifyContext OPTIONAL,
37 IN CONST EFI_GUID *EventGroup OPTIONAL,
38 OUT EFI_EVENT *Event
39 )
40{
41 if ((Type == EVT_NOTIFY_SIGNAL) && CompareGuid (EventGroup, &gEfiEventExitBootServicesGuid)) {
42 return gBS->CreateEvent (
43 EVT_SIGNAL_EXIT_BOOT_SERVICES,
44 NotifyTpl,
45 NotifyFunction,
46 (VOID *)NotifyContext,
47 Event
48 );
49 }
50
51 if ((Type == EVT_NOTIFY_SIGNAL) && CompareGuid (EventGroup, &gEfiEventVirtualAddressChangeGuid)) {
52 return gBS->CreateEvent (
53 EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
54 NotifyTpl,
55 NotifyFunction,
56 (VOID *)NotifyContext,
57 Event
58 );
59 }
60
61 gBS->CreateEvent (
62 Type,
63 NotifyTpl,
64 NotifyFunction,
65 (VOID *)NotifyContext,
66 Event
67 );
68 return EFI_SUCCESS;
69}
70
71//
72// The Trash strategy relies on old Apple firmware allocating gBS and gDS consecutively.
73// This layout is directly inherited from standard edk EFI code.
74// The strategy trashes the DXE_SERVICES_SIGNATURE value in gDS->Hdr.Signature, which
75// happily is only used when the memory is being loaded (when we check for references
76// to DXE_SERVICES_SIGNATURE throughout the edk code).
77// For the Trash strategy to work, we are required to trash exactly that QWORD of memory,
78// but in the targeted firmware we can confirm that it is harmless to do so before proceeding.
79//
80EFI_STATUS
82 IN BOOLEAN Forge,
83 IN BOOLEAN Trash
84 )
85{
86 EFI_BOOT_SERVICES *NewBS;
87
88 DEBUG ((
89 DEBUG_INFO,
90 "OCDM: Found 0x%X/0x%X UEFI version (%u bytes, %u %a to %u) gST %p gBS %p gBS->CreateEventEx %p &gBS %p\n",
91 gST->Hdr.Revision,
92 gBS->Hdr.Revision,
93 gBS->Hdr.HeaderSize,
94 Forge,
95 Trash ? "trashing" : "rebuilding",
96 (UINT32)sizeof (EFI_BOOT_SERVICES),
97 gST,
98 gBS,
99 gBS->CreateEventEx,
100 &gBS
101 ));
102
103 if (!Forge) {
104 return EFI_SUCCESS;
105 }
106
107 //
108 // Already too new.
109 // This check will replace any earlier forge to 2.0 <= UEFI < 2.3.
110 // This is desirable in some cases and harmless in others.
111 //
112 if (gST->Hdr.Revision >= EFI_2_30_SYSTEM_TABLE_REVISION) {
113 return EFI_ALREADY_STARTED;
114 }
115
116 if (gBS->Hdr.HeaderSize > OFFSET_OF (EFI_BOOT_SERVICES, CreateEventEx)) {
117 return EFI_INVALID_PARAMETER;
118 }
119
120 if (Trash) {
121 if ((VOID *)&gBS->CreateEventEx != (VOID *)gDS) {
122 DEBUG ((
123 DEBUG_WARN,
124 "OCDM: Aborting trash strategy, gDS does not follow gBS\n"
125 ));
126 return EFI_UNSUPPORTED;
127 }
128
129 DEBUG ((
130 DEBUG_INFO,
131 "OCDM: Trashing gDS->Hdr.Signature with gBS->CreateEventEx\n"
132 ));
133 NewBS = gBS;
134 } else {
135 NewBS = AllocateZeroPool (sizeof (EFI_BOOT_SERVICES));
136 if (NewBS == NULL) {
137 DEBUG ((DEBUG_INFO, "OCDM: Failed to allocate BS copy\n"));
138 return EFI_OUT_OF_RESOURCES;
139 }
140
141 CopyMem (NewBS, gBS, gBS->Hdr.HeaderSize);
142 }
143
144 NewBS->CreateEventEx = OcCreateEventEx;
145 NewBS->Hdr.HeaderSize = sizeof (EFI_BOOT_SERVICES);
146 NewBS->Hdr.Revision = EFI_2_30_SYSTEM_TABLE_REVISION;
147 NewBS->Hdr.CRC32 = 0;
148 NewBS->Hdr.CRC32 = CalculateCrc32 (NewBS, NewBS->Hdr.HeaderSize);
149 gBS = NewBS;
150
151 gST->BootServices = NewBS;
152 gST->Hdr.Revision = EFI_2_30_SYSTEM_TABLE_REVISION;
153 gST->Hdr.CRC32 = 0;
154 gST->Hdr.CRC32 = CalculateCrc32 (gST, gST->Hdr.HeaderSize);
155
156 if (Trash) {
157 gDS->Hdr.CRC32 = 0;
158 gDS->Hdr.CRC32 = CalculateCrc32 (gDS, gDS->Hdr.HeaderSize);
159 }
160
161 return EFI_SUCCESS;
162}
EFI_STATUS OcForgeUefiSupport(IN BOOLEAN Forge, IN BOOLEAN Trash)
Definition ForgeUefi.c:81
STATIC EFI_STATUS EFIAPI OcCreateEventEx(IN UINT32 Type, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, IN CONST VOID *NotifyContext OPTIONAL, IN CONST EFI_GUID *EventGroup OPTIONAL, OUT EFI_EVENT *Event)
Definition ForgeUefi.c:32
EFI_SYSTEM_TABLE * gST
EFI_BOOT_SERVICES * gBS
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)