summaryrefslogtreecommitdiff
path: root/InOsEmuPkg
diff options
context:
space:
mode:
Diffstat (limited to 'InOsEmuPkg')
-rw-r--r--InOsEmuPkg/CpuRuntimeDxe/Cpu.c33
-rw-r--r--InOsEmuPkg/CpuRuntimeDxe/Cpu.inf3
-rw-r--r--InOsEmuPkg/CpuRuntimeDxe/CpuDriver.h1
-rw-r--r--InOsEmuPkg/Include/Protocol/EmuThunk.h7
-rw-r--r--InOsEmuPkg/Unix/Sec/EmuThunk.c17
-rw-r--r--InOsEmuPkg/Unix/Sec/Gasket.h6
-rw-r--r--InOsEmuPkg/Unix/Sec/X11GraphicsWindow.c63
-rw-r--r--InOsEmuPkg/Unix/Sec/X64/Gasket.S16
8 files changed, 104 insertions, 42 deletions
diff --git a/InOsEmuPkg/CpuRuntimeDxe/Cpu.c b/InOsEmuPkg/CpuRuntimeDxe/Cpu.c
index 472b1c3..5ec315b 100644
--- a/InOsEmuPkg/CpuRuntimeDxe/Cpu.c
+++ b/InOsEmuPkg/CpuRuntimeDxe/Cpu.c
@@ -305,6 +305,27 @@ CpuUpdateSmbios (
FreePool (SmbiosRecord);
}
+
+
+/**
+ Callback function for idle events.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context The pointer to the notification function's context,
+ which is implementation-dependent.
+
+**/
+VOID
+EFIAPI
+IdleLoopEventCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ gEmuThunk->CpuSleep ();
+}
+
+
EFI_STATUS
EFIAPI
InitializeCpu (
@@ -314,6 +335,7 @@ InitializeCpu (
{
EFI_STATUS Status;
UINT64 Frequency;
+ EFI_EVENT IdleLoopEvent;
//
// Retrieve the frequency of the performance counter in Hz.
@@ -328,6 +350,17 @@ InitializeCpu (
CpuUpdateSmbios ();
CpuMpServicesInit ();
+
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ IdleLoopEventCallback,
+ NULL,
+ &gIdleLoopEventGuid,
+ &IdleLoopEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
Status = gBS->InstallMultipleProtocolInterfaces (
&mCpuTemplate.Handle,
diff --git a/InOsEmuPkg/CpuRuntimeDxe/Cpu.inf b/InOsEmuPkg/CpuRuntimeDxe/Cpu.inf
index 6fc240c..d548c8a 100644
--- a/InOsEmuPkg/CpuRuntimeDxe/Cpu.inf
+++ b/InOsEmuPkg/CpuRuntimeDxe/Cpu.inf
@@ -66,6 +66,9 @@
gEmuThreadThunkProtocolGuid
gEfiMpServiceProtocolGuid
+[Guids]
+ gIdleLoopEventGuid ## CONSUMES ## GUID
+
[Pcd]
gInOsEmuPkgTokenSpaceGuid.PcdEmuMpServicesPollingInterval
diff --git a/InOsEmuPkg/CpuRuntimeDxe/CpuDriver.h b/InOsEmuPkg/CpuRuntimeDxe/CpuDriver.h
index 3ef2511..69505ff 100644
--- a/InOsEmuPkg/CpuRuntimeDxe/CpuDriver.h
+++ b/InOsEmuPkg/CpuRuntimeDxe/CpuDriver.h
@@ -28,6 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/CpuIo2.h>
#include <Guid/DataHubRecords.h>
+#include <Guid/IdleLoopEvent.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
diff --git a/InOsEmuPkg/Include/Protocol/EmuThunk.h b/InOsEmuPkg/Include/Protocol/EmuThunk.h
index 3e2718e..ed4df3a 100644
--- a/InOsEmuPkg/Include/Protocol/EmuThunk.h
+++ b/InOsEmuPkg/Include/Protocol/EmuThunk.h
@@ -130,6 +130,12 @@ VOID
typedef
VOID
+(EFIAPI *EMU_CPU_SLEEP) (
+ VOID
+ );
+
+typedef
+VOID
(EFIAPI *EMU_EXIT) (
IN UINTN Status
);
@@ -215,6 +221,7 @@ struct _EMU_THUNK_PROTOCOL {
EMU_QUERY_PERFORMANCE_COUNTER QueryPerformanceCounter;
EMU_SLEEP Sleep;
+ EMU_CPU_SLEEP CpuSleep;
EMU_EXIT Exit;
EMU_GET_TIME GetTime;
EMU_SET_TIME SetTime;
diff --git a/InOsEmuPkg/Unix/Sec/EmuThunk.c b/InOsEmuPkg/Unix/Sec/EmuThunk.c
index 579f67f..ca8be55 100644
--- a/InOsEmuPkg/Unix/Sec/EmuThunk.c
+++ b/InOsEmuPkg/Unix/Sec/EmuThunk.c
@@ -286,6 +286,22 @@ SecSleep (
}
}
+
+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
@@ -362,6 +378,7 @@ EMU_THUNK_PROTOCOL gEmuThunkProtocol = {
GasketQueryPerformanceFrequency,
GasketQueryPerformanceCounter,
GasketSecSleep,
+ GasketSecCpuSleep,
GasketSecExit,
GasketSecGetTime,
GasketSecSetTime,
diff --git a/InOsEmuPkg/Unix/Sec/Gasket.h b/InOsEmuPkg/Unix/Sec/Gasket.h
index 2234bbe..0862b2c 100644
--- a/InOsEmuPkg/Unix/Sec/Gasket.h
+++ b/InOsEmuPkg/Unix/Sec/Gasket.h
@@ -108,6 +108,12 @@ VOID
EFIAPI
GasketSecSleep (
IN UINT64 Milliseconds
+
+ );
+VOID
+EFIAPI
+GasketSecCpuSleep (
+ VOID
);
VOID
diff --git a/InOsEmuPkg/Unix/Sec/X11GraphicsWindow.c b/InOsEmuPkg/Unix/Sec/X11GraphicsWindow.c
index 72c4544..10c591d 100644
--- a/InOsEmuPkg/Unix/Sec/X11GraphicsWindow.c
+++ b/InOsEmuPkg/Unix/Sec/X11GraphicsWindow.c
@@ -624,24 +624,6 @@ X11ColorToPixel (
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 (
@@ -652,7 +634,13 @@ 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
@@ -667,7 +655,7 @@ X11GetKey (
Drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo;
- EfiStatus = CheckKeyInternal (Drv, FALSE);
+ EfiStatus = X11CheckKey (GraphicsIo);
if (EFI_ERROR (EfiStatus)) {
return EfiStatus;
}
@@ -879,24 +867,6 @@ X11Blt (
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 (
@@ -907,23 +877,32 @@ 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;
diff --git a/InOsEmuPkg/Unix/Sec/X64/Gasket.S b/InOsEmuPkg/Unix/Sec/X64/Gasket.S
index a51807a..d30aed6 100644
--- a/InOsEmuPkg/Unix/Sec/X64/Gasket.S
+++ b/InOsEmuPkg/Unix/Sec/X64/Gasket.S
@@ -227,6 +227,22 @@ ASM_PFX(GasketSecSleep):
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