From: Ruiyu Ni <ruiyu.ni@intel.com>
To: edk2-devel@lists.01.org
Cc: Hao Wu <hao.a.wu@intel.com>, Andrew Fish <afish@intel.com>
Subject: [PATCH 06/12] EmulatorPkg/Win: Add timer and interrupt support
Date: Thu, 23 Aug 2018 17:52:09 +0800 [thread overview]
Message-ID: <20180823095215.274248-7-ruiyu.ni@intel.com> (raw)
In-Reply-To: <20180823095215.274248-1-ruiyu.ni@intel.com>
Now the firmware can boot to Shell and count down 5 seconds to
command prompt.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Andrew Fish <afish@intel.com>
---
EmulatorPkg/Win/Host/WinThunk.c | 194 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 194 insertions(+)
diff --git a/EmulatorPkg/Win/Host/WinThunk.c b/EmulatorPkg/Win/Host/WinThunk.c
index 69a61258f3..ffe71aef9a 100644
--- a/EmulatorPkg/Win/Host/WinThunk.c
+++ b/EmulatorPkg/Win/Host/WinThunk.c
@@ -205,12 +205,193 @@ SecFree (
return TRUE;
}
+
+
+//
+// Define a global that we can use to shut down the NT timer thread when
+// the timer is canceled.
+//
+BOOLEAN mCancelTimerThread = FALSE;
+
+//
+// The notification function to call on every timer interrupt
+//
+EMU_SET_TIMER_CALLBACK *mTimerNotifyFunction = NULL;
+
+//
+// The thread handle for this driver
+//
+HANDLE mNtMainThreadHandle;
+
+//
+// The timer value from the last timer interrupt
+//
+UINT32 mNtLastTick;
+
+//
+// Critical section used to update varibles shared between the main thread and
+// the timer interrupt thread.
+//
+CRITICAL_SECTION mNtCriticalSection;
+
+//
+// Worker Functions
+//
+UINT mMMTimerThreadID = 0;
+
+volatile BOOLEAN mInterruptEnabled = FALSE;
+
+VOID
+CALLBACK
+MMTimerThread (
+ UINT wTimerID,
+ UINT msg,
+ DWORD dwUser,
+ DWORD dw1,
+ DWORD dw2
+)
+{
+ UINT32 CurrentTick;
+ UINT32 Delta;
+
+ if (!mCancelTimerThread) {
+
+ //
+ // Suspend the main thread until we are done.
+ // Enter the critical section before suspending
+ // and leave the critical section after resuming
+ // to avoid deadlock between main and timer thread.
+ //
+ EnterCriticalSection (&mNtCriticalSection);
+ SuspendThread (mNtMainThreadHandle);
+
+ //
+ // If the timer thread is being canceled, then bail immediately.
+ // We check again here because there's a small window of time from when
+ // this thread was kicked off and when we suspended the main thread above.
+ //
+ if (mCancelTimerThread) {
+ ResumeThread (mNtMainThreadHandle);
+ LeaveCriticalSection (&mNtCriticalSection);
+ timeKillEvent (wTimerID);
+ mMMTimerThreadID = 0;
+ return;
+ }
+
+ while (!mInterruptEnabled) {
+ //
+ // Resume the main thread
+ //
+ ResumeThread (mNtMainThreadHandle);
+ LeaveCriticalSection (&mNtCriticalSection);
+
+ //
+ // Wait for interrupts to be enabled.
+ //
+ while (!mInterruptEnabled) {
+ Sleep (1);
+ }
+
+ //
+ // Suspend the main thread until we are done
+ //
+ EnterCriticalSection (&mNtCriticalSection);
+ SuspendThread (mNtMainThreadHandle);
+ }
+
+ //
+ // Get the current system tick
+ //
+ CurrentTick = GetTickCount ();
+ Delta = CurrentTick - mNtLastTick;
+ mNtLastTick = CurrentTick;
+
+ //
+ // If delay was more then 1 second, ignore it (probably debugging case)
+ //
+ if (Delta < 1000) {
+
+ //
+ // Only invoke the callback function if a Non-NULL handler has been
+ // registered. Assume all other handlers are legal.
+ //
+ if (mTimerNotifyFunction != NULL) {
+ mTimerNotifyFunction (Delta);
+ }
+ }
+
+ //
+ // Resume the main thread
+ //
+ ResumeThread (mNtMainThreadHandle);
+ LeaveCriticalSection (&mNtCriticalSection);
+ } else {
+ timeKillEvent (wTimerID);
+ mMMTimerThreadID = 0;
+ }
+
+}
+
VOID
SecSetTimer (
IN UINT64 TimerPeriod,
IN EMU_SET_TIMER_CALLBACK Callback
)
{
+ //
+// If TimerPeriod is 0, then the timer thread should be canceled
+//
+ if (TimerPeriod == 0) {
+ //
+ // Cancel the timer thread
+ //
+ EnterCriticalSection (&mNtCriticalSection);
+
+ mCancelTimerThread = TRUE;
+
+ LeaveCriticalSection (&mNtCriticalSection);
+
+ //
+ // Wait for the timer thread to exit
+ //
+
+ if (mMMTimerThreadID != 0) {
+ timeKillEvent (mMMTimerThreadID);
+ mMMTimerThreadID = 0;
+ }
+ } else {
+ //
+ // If the TimerPeriod is valid, then create and/or adjust the period of the timer thread
+ //
+ EnterCriticalSection (&mNtCriticalSection);
+
+ mCancelTimerThread = FALSE;
+
+ LeaveCriticalSection (&mNtCriticalSection);
+
+ //
+ // Get the starting tick location if we are just starting the timer thread
+ //
+ mNtLastTick = GetTickCount ();
+
+ if (mMMTimerThreadID) {
+ timeKillEvent (mMMTimerThreadID);
+ }
+
+ SetThreadPriority (
+ GetCurrentThread (),
+ THREAD_PRIORITY_HIGHEST
+ );
+
+ mMMTimerThreadID = timeSetEvent (
+ (UINT)TimerPeriod,
+ 0,
+ MMTimerThread,
+ (DWORD_PTR)NULL,
+ TIME_PERIODIC | TIME_KILL_SYNCHRONOUS | TIME_CALLBACK_FUNCTION
+ );
+ }
+ mTimerNotifyFunction = Callback;
}
VOID
@@ -218,6 +399,17 @@ SecInitializeThunk (
VOID
)
{
+ InitializeCriticalSection (&mNtCriticalSection);
+
+ DuplicateHandle (
+ GetCurrentProcess (),
+ GetCurrentThread (),
+ GetCurrentProcess (),
+ &mNtMainThreadHandle,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS
+ );
}
VOID
@@ -225,6 +417,7 @@ SecEnableInterrupt (
VOID
)
{
+ mInterruptEnabled = TRUE;
}
@@ -233,6 +426,7 @@ SecDisableInterrupt (
VOID
)
{
+ mInterruptEnabled = FALSE;
}
--
2.16.1.windows.1
next prev parent reply other threads:[~2018-08-23 9:51 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-23 9:52 [PATCH 00/12] Add WinHost support in EmulatorPkg Ruiyu Ni
2018-08-23 9:52 ` [PATCH 01/12] EmulatorPkg/ThunkProtocolList: Fix VS build failure Ruiyu Ni
2018-08-23 9:52 ` [PATCH 02/12] EmulatorPkg/Win: Add Windows host support Ruiyu Ni
2018-08-23 9:52 ` [PATCH 03/12] EmulatorPkg/Win: Enable source level debugging Ruiyu Ni
2018-08-23 9:52 ` [PATCH 04/12] EmulatorPkg/Win: Enable native OS console as firmware console Ruiyu Ni
2018-08-23 9:52 ` [PATCH 05/12] EmulatorPkg/Win: Add input/output support Ruiyu Ni
2018-08-23 9:52 ` Ruiyu Ni [this message]
2018-08-23 9:52 ` [PATCH 07/12] EmulatorPkg/Win: Add RTC support Ruiyu Ni
2018-08-23 9:52 ` [PATCH 08/12] EmulatorPkg/Win: Add SimpleFileSystem support Ruiyu Ni
2018-08-23 9:52 ` [PATCH 09/12] EmulatorPkg/Win: Add BlockIo support Ruiyu Ni
2018-08-23 9:52 ` [PATCH 10/12] EmulatorPkg/PlatformBds: Signal EndOfDxe in platform BDS Ruiyu Ni
2018-08-23 9:52 ` [PATCH 11/12] EmulatorPkg/EmuFileSystem: Fix a bug that causes Close() assertion Ruiyu Ni
2018-08-23 9:52 ` [PATCH 12/12] EmulatorPkg/DSC: Remove FS mapping to EDK Shell bin directory Ruiyu Ni
2018-08-23 9:56 ` [PATCH 00/12] Add WinHost support in EmulatorPkg Ni, Ruiyu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180823095215.274248-7-ruiyu.ni@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox