FreePool (SmbiosRecord);\r
}\r
\r
+\r
+\r
+/**\r
+ Callback function for idle events.\r
+ \r
+ @param Event Event whose notification function is being invoked.\r
+ @param Context The pointer to the notification function's context,\r
+ which is implementation-dependent.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+IdleLoopEventCallback (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ gEmuThunk->CpuSleep ();\r
+}\r
+\r
+\r
EFI_STATUS\r
EFIAPI\r
InitializeCpu (\r
{\r
EFI_STATUS Status;\r
UINT64 Frequency;\r
+ EFI_EVENT IdleLoopEvent;\r
\r
//\r
// Retrieve the frequency of the performance counter in Hz.\r
CpuUpdateSmbios ();\r
\r
CpuMpServicesInit ();\r
+ \r
+ Status = gBS->CreateEventEx (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ IdleLoopEventCallback,\r
+ NULL,\r
+ &gIdleLoopEventGuid,\r
+ &IdleLoopEvent\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
&mCpuTemplate.Handle,\r
gEmuThreadThunkProtocolGuid\r
gEfiMpServiceProtocolGuid\r
\r
+[Guids]\r
+ gIdleLoopEventGuid ## CONSUMES ## GUID\r
+\r
[Pcd]\r
gInOsEmuPkgTokenSpaceGuid.PcdEmuMpServicesPollingInterval\r
\r
#include <Protocol/CpuIo2.h>\r
\r
#include <Guid/DataHubRecords.h>\r
+#include <Guid/IdleLoopEvent.h>\r
\r
#include <Library/BaseLib.h>\r
#include <Library/DebugLib.h>\r
IN UINT64 Milliseconds\r
);\r
\r
+typedef\r
+VOID\r
+(EFIAPI *EMU_CPU_SLEEP) (\r
+ VOID\r
+ );\r
+\r
typedef\r
VOID\r
(EFIAPI *EMU_EXIT) (\r
EMU_QUERY_PERFORMANCE_COUNTER QueryPerformanceCounter;\r
\r
EMU_SLEEP Sleep;\r
+ EMU_CPU_SLEEP CpuSleep;\r
EMU_EXIT Exit;\r
EMU_GET_TIME GetTime; \r
EMU_SET_TIME SetTime;\r
}
}
+
+VOID
+SecCpuSleep (
+ VOID
+ )
+{
+ struct timespec rq, rm;
+
+ // nanosleep gets interrupted by the timer tic
+ rq.tv_sec = 1;
+ rq.tv_nsec = 0;
+
+ nanosleep (&rq, &rm);
+}
+
+
VOID
SecExit (
UINTN Status
GasketQueryPerformanceFrequency,
GasketQueryPerformanceCounter,
GasketSecSleep,
+ GasketSecCpuSleep,
GasketSecExit,
GasketSecGetTime,
GasketSecSetTime,
EFIAPI\r
GasketSecSleep (\r
IN UINT64 Milliseconds\r
+\r
+ );\r
+VOID\r
+EFIAPI\r
+GasketSecCpuSleep (\r
+ VOID\r
);\r
\r
VOID\r
return Pixel;
}
-EFI_STATUS
-CheckKeyInternal (
- IN GRAPHICS_IO_PRIVATE *Drv,
- IN BOOLEAN delay
- )
-{
- HandleEvents (Drv);
-
- if (Drv->key_count != 0) {
- return EFI_SUCCESS;
- }
-
- if (delay) {
- // EFI is polling. Be CPU-friendly.
- SecSleep (20);
- }
- return EFI_NOT_READY;
-}
EFI_STATUS
X11CheckKey (
Drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo;
- return CheckKeyInternal (Drv, TRUE);
+ HandleEvents (Drv);
+
+ if (Drv->key_count != 0) {
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_READY;
}
EFI_STATUS
Drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo;
- EfiStatus = CheckKeyInternal (Drv, FALSE);
+ EfiStatus = X11CheckKey (GraphicsIo);
if (EFI_ERROR (EfiStatus)) {
return EfiStatus;
}
return EFI_SUCCESS;
}
-EFI_STATUS
-CheckPointerInternal (
- IN GRAPHICS_IO_PRIVATE *Drv,
- IN BOOLEAN delay
- )
-{
- HandleEvents (Drv);
- if (Drv->pointer_state_changed != 0) {
- return EFI_SUCCESS;
- }
-
- if ( delay ) {
- // EFI is polling. Be CPU-friendly.
- SecSleep (20);
- }
-
- return EFI_NOT_READY;
-}
EFI_STATUS
X11CheckPointer (
Drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo;
- return CheckPointerInternal (Drv, TRUE);
+ HandleEvents (Drv);
+ if (Drv->pointer_state_changed != 0) {
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_READY;
}
+
EFI_STATUS
-X11GetPointerState (EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, EFI_SIMPLE_POINTER_STATE *state)
+X11GetPointerState (
+ IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo,
+ IN EFI_SIMPLE_POINTER_STATE *State
+ )
{
EFI_STATUS EfiStatus;
GRAPHICS_IO_PRIVATE *Drv;
Drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo;
- EfiStatus = CheckPointerInternal (Drv, FALSE);
+ EfiStatus = X11CheckPointer (GraphicsIo);
if (EfiStatus != EFI_SUCCESS) {
return EfiStatus;
}
- memcpy (state, &Drv->pointer_state, sizeof (EFI_SIMPLE_POINTER_STATE));
+ memcpy (State, &Drv->pointer_state, sizeof (EFI_SIMPLE_POINTER_STATE));
Drv->pointer_state.RelativeMovementX = 0;
Drv->pointer_state.RelativeMovementY = 0;
ret
+ASM_GLOBAL ASM_PFX(GasketSecCpuSleep)
+ASM_PFX(GasketSecCpuSleep):
+ pushq %rbp // stack frame is for the debugger
+ movq %rsp, %rbp
+
+ pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI
+ pushq %rdi
+
+ call ASM_PFX(SecCpuSleep)
+
+ popq %rdi // restore state
+ popq %rsi
+ popq %rbp
+ ret
+
+
ASM_GLOBAL ASM_PFX(GasketSecExit)
ASM_PFX(GasketSecExit):
pushq %rbp // stack frame is for the debugger