OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
AIK.c
Go to the documentation of this file.
1
15#include <Uefi.h>
16
17#include "AIK.h"
18
19#include <Library/DebugLib.h>
20#include <Library/OcInputLib.h>
21#include <Library/UefiBootServicesTableLib.h>
22
24
25STATIC
26VOID
27EFIAPI
29 IN EFI_EVENT Event,
30 IN VOID *Context
31 )
32{
33 EFI_STATUS Status;
34 AIK_SELF *Keycode;
35
36 Keycode = (AIK_SELF *)Context;
37
38 if ((Keycode == NULL) || Keycode->OurJobIsDone) {
39 DEBUG ((DEBUG_INFO, "AIK: ProtocolArriveHandler got null handler or called when done\n"));
40 return;
41 }
42
43 Status = AIKInstall (Keycode);
44 if (!EFI_ERROR (Status)) {
45 //
46 // We are successful, so can remove the protocol polling event if any
47 //
49 } else {
50 DEBUG ((DEBUG_INFO, "AIK: ProtocolArriveHandler AIKInstall failed - %r\n", Status));
51 }
52}
53
54EFI_STATUS
56 AIK_SELF *Keycode
57 )
58{
59 EFI_STATUS Status;
60 VOID *Registration;
61
62 Status = EFI_SUCCESS;
63
64 if (Keycode->KeyMapDbArriveEvent == NULL) {
65 Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, AIKProtocolArriveHandler, Keycode, &Keycode->KeyMapDbArriveEvent);
66
67 if (EFI_ERROR (Status)) {
68 DEBUG ((DEBUG_INFO, "KeyMapDbArriveEvent creation failed - %r\n", Status));
69 } else {
70 Status = gBS->RegisterProtocolNotify (&gAppleKeyMapDatabaseProtocolGuid, Keycode->KeyMapDbArriveEvent, &Registration);
71
72 if (EFI_ERROR (Status)) {
73 DEBUG ((DEBUG_INFO, "KeyMapDbArriveEvent registration failed - %r\n", Status));
74 gBS->CloseEvent (Keycode->KeyMapDbArriveEvent);
75 Keycode->KeyMapDbArriveEvent = NULL;
76 }
77 }
78 }
79
80 return Status;
81}
82
83VOID
85 AIK_SELF *Keycode
86 )
87{
88 if (Keycode->KeyMapDbArriveEvent != NULL) {
89 gBS->CloseEvent (Keycode->KeyMapDbArriveEvent);
90 Keycode->KeyMapDbArriveEvent = NULL;
91 }
92}
93
94VOID
95EFIAPI
97 IN EFI_EVENT Event,
98 IN VOID *Context
99 )
100{
101 AIK_SELF *Keycode;
102 UINT64 Counter;
103 UINTN Index;
104 AMI_EFI_KEY_DATA KeyData;
105 EFI_STATUS Status;
106
107 Keycode = (AIK_SELF *)Context;
108 if ((Keycode == NULL) || Keycode->OurJobIsDone) {
109 DEBUG ((DEBUG_INFO, "AIK: PollKeyboardHandler got null handler or called when done\n"));
110 return;
111 }
112
113 //
114 // Timer handlers may not always be serialised as discovered in Toshiba Portege z30a.
115 // REF: https://github.com/acidanthera/bugtracker/issues/1340
116 //
117 if (Keycode->InPollKeyboardEvent) {
118 return;
119 }
120
121 Keycode->InPollKeyboardEvent = TRUE;
122
123 //
124 // Counter is here for debugging purposes only.
125 //
126 Counter = AIKTargetRefresh (&Keycode->Target);
127
128 //
129 // Some implementations return "partial key", which is a modifier without
130 // a key. When a modifier is held, we will get partial keys infinitely, so make sure
131 // we break after some time.
132 //
133 Index = 0;
134
135 do {
136 Status = AIKSourceGrabEfiKey (
137 &Keycode->Source,
138 &KeyData,
139 Keycode->KeyFiltering
140 );
141 if (!EFI_ERROR (Status)) {
142 DEBUG ((
143 DEBUG_VERBOSE,
144 "AIK: Key scan 0x%X uni 0x%X Shift 0x%X toggle 0x%X at %Lu\n",
145 KeyData.Key.ScanCode,
146 KeyData.Key.UnicodeChar,
147 KeyData.KeyState.KeyShiftState,
148 KeyData.KeyState.KeyToggleState,
149 Counter
150 ));
151 AIKDataWriteEntry (&Keycode->Data, &KeyData);
152 AIKTargetWriteEntry (&Keycode->Target, &KeyData);
153 } else if (Status == EFI_UNSUPPORTED) {
154 //
155 // Filtered key, do not abort.
156 //
157 Status = EFI_SUCCESS;
158 }
159
160 Index++;
161 } while (!EFI_ERROR (Status) && Index < AIK_KEY_POLL_LIMIT);
162
163 AIKTargetSubmit (&Keycode->Target);
164
165 Keycode->InPollKeyboardEvent = FALSE;
166}
167
168EFI_STATUS
170 AIK_SELF *Keycode
171 )
172{
173 EFI_STATUS Status;
174
175 Status = AIKTargetInstall (
176 &Keycode->Target,
177 Keycode->KeyForgotThreshold
178 );
179
180 if (EFI_ERROR (Status)) {
181 //
182 // Working AppleKeyMapAggregator is not here yet.
183 //
184 return Status;
185 }
186
187 Status = AIKSourceInstall (&Keycode->Source, Keycode->Mode);
188
189 if (EFI_ERROR (Status)) {
190 //
191 // Cannot work with these sources.
192 //
193 AIKTargetUninstall (&Keycode->Target);
194 return Status;
195 }
196
197 AIKDataReset (&Keycode->Data);
198
199 Status = gBS->CreateEvent (
200 EVT_TIMER | EVT_NOTIFY_SIGNAL,
201 TPL_NOTIFY,
203 Keycode,
204 &Keycode->PollKeyboardEvent
205 );
206
207 if (!EFI_ERROR (Status)) {
208 Status = gBS->SetTimer (Keycode->PollKeyboardEvent, TimerPeriodic, AIK_KEY_POLL_INTERVAL);
209 if (EFI_ERROR (Status)) {
210 DEBUG ((DEBUG_INFO, "AIK: PollKeyboardHandler timer setting failed - %r\n", Status));
211 gBS->CloseEvent (Keycode->PollKeyboardEvent);
212 Keycode->PollKeyboardEvent = NULL;
213 }
214 } else {
215 DEBUG ((DEBUG_INFO, "AIK: PollKeyboardHandler event creation failed - %r\n", Status));
216 }
217
218 if (EFI_ERROR (Status)) {
219 AIKSourceUninstall (&Keycode->Source);
220 AIKTargetUninstall (&Keycode->Target);
221 }
222
223 return Status;
224}
225
226VOID
228 AIK_SELF *Keycode
229 )
230{
231 Keycode->OurJobIsDone = TRUE;
232
234
235 if (Keycode->PollKeyboardEvent) {
236 gBS->SetTimer (Keycode->PollKeyboardEvent, TimerCancel, 0);
237 gBS->CloseEvent (Keycode->PollKeyboardEvent);
238 Keycode->PollKeyboardEvent = NULL;
239 }
240
241 AIKSourceUninstall (&Keycode->Source);
242 AIKTargetUninstall (&Keycode->Target);
243}
244
245EFI_STATUS
247 IN OC_INPUT_KEY_MODE Mode,
248 IN UINT8 KeyForgotThreshold,
249 IN BOOLEAN KeySwap,
250 IN BOOLEAN KeyFiltering
251 )
252{
253 EFI_STATUS Status;
254
255 AIKTranslateConfigure (KeySwap);
256
257 gAikSelf.Mode = Mode;
258 gAikSelf.KeyForgotThreshold = KeyForgotThreshold;
259 gAikSelf.KeyFiltering = KeyFiltering;
260 Status = AIKInstall (&gAikSelf);
261
262 if (EFI_ERROR (Status)) {
263 //
264 // No AppleKeyMapAggregator present, install on its availability.
265 //
267 if (EFI_ERROR (Status)) {
268 //
269 // Note: Even with no kb support (e.g. detachable keyboard) system can still boot via timeout
270 //
271 DEBUG ((DEBUG_INFO, "AIK: NOT waiting for protocols - %r\n", Status));
272 }
273 }
274
275 if (!EFI_ERROR (Status)) {
276 DEBUG ((DEBUG_INFO, "AIK: Using %d (%d0ms)\n", KeyForgotThreshold, KeyForgotThreshold));
277 }
278
279 return Status;
280}
281
282EFI_STATUS
284 VOID
285 )
286{
288 return EFI_SUCCESS;
289}
AIK_SELF gAikSelf
Definition AIK.c:23
VOID AIKProtocolArriveUninstall(AIK_SELF *Keycode)
Definition AIK.c:84
EFI_STATUS AIKProtocolArriveInstall(AIK_SELF *Keycode)
Definition AIK.c:55
EFI_STATUS OcAppleGenericInputKeycodeInit(IN OC_INPUT_KEY_MODE Mode, IN UINT8 KeyForgotThreshold, IN BOOLEAN KeySwap, IN BOOLEAN KeyFiltering)
Definition AIK.c:246
VOID EFIAPI AIKPollKeyboardHandler(IN EFI_EVENT Event, IN VOID *Context)
Definition AIK.c:96
VOID AIKUninstall(AIK_SELF *Keycode)
Definition AIK.c:227
EFI_STATUS AIKInstall(AIK_SELF *Keycode)
Definition AIK.c:169
STATIC VOID EFIAPI AIKProtocolArriveHandler(IN EFI_EVENT Event, IN VOID *Context)
Definition AIK.c:28
EFI_STATUS OcAppleGenericInputKeycodeExit(VOID)
Definition AIK.c:283
#define AIK_KEY_POLL_LIMIT
Definition AIK.h:29
#define AIK_KEY_POLL_INTERVAL
Definition AIK.h:34
VOID AIKDataReset(IN OUT AIK_DATA *Data)
Definition AIKData.c:21
VOID AIKDataWriteEntry(IN OUT AIK_DATA *Data, IN AMI_EFI_KEY_DATA *KeyData)
Definition AIKData.c:59
EFI_STATUS AIKSourceInstall(AIK_SOURCE *Source, OC_INPUT_KEY_MODE Mode)
Definition AIKSource.c:128
EFI_STATUS AIKSourceGrabEfiKey(AIK_SOURCE *Source, AMI_EFI_KEY_DATA *KeyData, BOOLEAN KeyFiltering)
Definition AIKSource.c:24
VOID AIKSourceUninstall(AIK_SOURCE *Source)
Definition AIKSource.c:239
VOID AIKTargetSubmit(IN OUT AIK_TARGET *Target)
Definition AIKTarget.c:179
VOID AIKTargetWriteEntry(IN OUT AIK_TARGET *Target, IN AMI_EFI_KEY_DATA *KeyData)
Definition AIKTarget.c:119
UINT64 AIKTargetRefresh(IN OUT AIK_TARGET *Target)
Definition AIKTarget.c:75
EFI_STATUS AIKTargetInstall(IN OUT AIK_TARGET *Target, IN UINT8 KeyForgotThreshold)
Definition AIKTarget.c:23
VOID AIKTargetUninstall(IN OUT AIK_TARGET *Target)
Definition AIKTarget.c:58
VOID AIKTranslateConfigure(IN BOOLEAN KeySwap)
EFI_GUID gAppleKeyMapDatabaseProtocolGuid
UINT32 Counter
EFI_BOOT_SERVICES * gBS
OC_INPUT_KEY_MODE
Definition OcInputLib.h:23
Definition AIK.h:36
BOOLEAN KeyFiltering
Definition AIK.h:50
AIK_TARGET Target
Definition AIK.h:60
UINT8 KeyForgotThreshold
Definition AIK.h:45
EFI_EVENT PollKeyboardEvent
Definition AIK.h:75
AIK_SOURCE Source
Definition AIK.h:55
OC_INPUT_KEY_MODE Mode
Definition AIK.h:40
BOOLEAN OurJobIsDone
Definition AIK.h:86
AIK_DATA Data
Definition AIK.h:65
EFI_EVENT KeyMapDbArriveEvent
Definition AIK.h:70
BOOLEAN InPollKeyboardEvent
Definition AIK.h:80
EFI_KEY_STATE KeyState
Definition AmiKeycode.h:32
EFI_INPUT_KEY Key
Definition AmiKeycode.h:31