mirror of https://github.com/acidanthera/audk.git
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
This commit is contained in:
parent
d8387fa4af
commit
57c7d70ff9
|
@ -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,
|
||||
|
|
|
@ -66,6 +66,9 @@
|
|||
gEmuThreadThunkProtocolGuid
|
||||
gEfiMpServiceProtocolGuid
|
||||
|
||||
[Guids]
|
||||
gIdleLoopEventGuid ## CONSUMES ## GUID
|
||||
|
||||
[Pcd]
|
||||
gInOsEmuPkgTokenSpaceGuid.PcdEmuMpServicesPollingInterval
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -128,6 +128,12 @@ VOID
|
|||
IN UINT64 Milliseconds
|
||||
);
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(EFIAPI *EMU_CPU_SLEEP) (
|
||||
VOID
|
||||
);
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(EFIAPI *EMU_EXIT) (
|
||||
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -108,6 +108,12 @@ VOID
|
|||
EFIAPI
|
||||
GasketSecSleep (
|
||||
IN UINT64 Milliseconds
|
||||
|
||||
);
|
||||
VOID
|
||||
EFIAPI
|
||||
GasketSecCpuSleep (
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue