]> git.proxmox.com Git - mirror_edk2.git/commitdiff
InOsEmuPkg: Implement gIdleLoopEventGuid.
authorandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 17 Jun 2011 18:21:16 +0000 (18:21 +0000)
committerandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 17 Jun 2011 18:21:16 +0000 (18:21 +0000)
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

InOsEmuPkg/CpuRuntimeDxe/Cpu.c
InOsEmuPkg/CpuRuntimeDxe/Cpu.inf
InOsEmuPkg/CpuRuntimeDxe/CpuDriver.h
InOsEmuPkg/Include/Protocol/EmuThunk.h
InOsEmuPkg/Unix/Sec/EmuThunk.c
InOsEmuPkg/Unix/Sec/Gasket.h
InOsEmuPkg/Unix/Sec/X11GraphicsWindow.c
InOsEmuPkg/Unix/Sec/X64/Gasket.S

index 472b1c3b736d5a57bdd1b7b16905d2bb427fb4c8..5ec315bea23f3a6f3d2f3eb2d38fad0a4a193d72 100644 (file)
@@ -305,6 +305,27 @@ CpuUpdateSmbios (
   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
@@ -314,6 +335,7 @@ InitializeCpu (
 {\r
   EFI_STATUS    Status;\r
   UINT64        Frequency;\r
+  EFI_EVENT     IdleLoopEvent;\r
 \r
   //\r
   // Retrieve the frequency of the performance counter in Hz.\r
@@ -328,6 +350,17 @@ InitializeCpu (
   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
index 6fc240c907a031b4d73af8b1209da0428c04dbf8..d548c8a41a14db46b920d722fc6c1fa17eee6565 100644 (file)
@@ -66,6 +66,9 @@
   gEmuThreadThunkProtocolGuid\r
   gEfiMpServiceProtocolGuid\r
 \r
+[Guids]\r
+  gIdleLoopEventGuid                            ## CONSUMES ## GUID\r
+\r
 [Pcd]\r
   gInOsEmuPkgTokenSpaceGuid.PcdEmuMpServicesPollingInterval\r
 \r
index 3ef251101ffd148e36bb386682124a1700b546e1..69505ff0e479ddbdc38a641018be0428a5a73eb5 100644 (file)
@@ -28,6 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #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
index 3e2718ed66f2813fc326e63872fa51f0ecc3923e..ed4df3a942e934a3d0b415541e0fa105be8a2c4c 100644 (file)
@@ -128,6 +128,12 @@ VOID
   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
@@ -215,6 +221,7 @@ struct _EMU_THUNK_PROTOCOL {
   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
index 579f67fa1adafda1bdaf9a531825a76a1f7bbb6d..ca8be55a0fd8ba4f1d377670bd501c51343f88e9 100644 (file)
@@ -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,
index 2234bbe8c691935583f43c8cf59e487afce8e0fd..0862b2c9ac55b30c04eebb90c47c591e2908cf7b 100644 (file)
@@ -108,6 +108,12 @@ VOID
 EFIAPI\r
 GasketSecSleep (\r
   IN  UINT64 Milliseconds\r
+\r
+  );\r
+VOID\r
+EFIAPI\r
+GasketSecCpuSleep (\r
+  VOID\r
   );\r
 \r
 VOID\r
index 72c4544ce592db73e83909bcc9d0b32eeb2f38e0..10c591d40359777bb1a552ca3652e203645b1deb 100644 (file)
@@ -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;
index a51807ab47998a9c20b275b6a6e51465ecdb2a71..d30aed617b5274ba854d66a790e3ec5f4a736441 100644 (file)
@@ -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