summaryrefslogtreecommitdiff
path: root/InOsEmuPkg
diff options
context:
space:
mode:
authorandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>2011-06-17 18:21:16 +0000
committerandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>2011-06-17 18:21:16 +0000
commit57c7d70ff9bcd4365d75b854046bbb390cb579c6 (patch)
treef55a5d5c20115d918df260ef03071015b36ee1d3 /InOsEmuPkg
parentd8387fa4af2abae05dc6ec502b27adea455cdaaa (diff)
downloadedk2-57c7d70ff9bcd4365d75b854046bbb390cb579c6.zip
edk2-57c7d70ff9bcd4365d75b854046bbb390cb579c6.tar.gz
edk2-57c7d70ff9bcd4365d75b854046bbb390cb579c6.tar.bz2
InOsEmuPkg: Implement gIdleLoopEventGuid.
Added a CpuSleep () API to the Emulator Thunk. We needed to do this as the Stall() works hard to not get broken by the timer tic (POSIX signal). nanosleep() gets interrupted by the timer signal so it is a good emulator of a CpuSleep(); I was also able to remove some stalls in the X11 keyboard and mouse checking events, now that the gIdleLoopEventGuid was added. Signed-off-by: andrewfish git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11846 6f19259b-4bc3-4df7-8a09-765794883524
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