>-----Original Message-----
>From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Heyi Guo
>Sent: Saturday, April 23, 2016 4:54 PM
>To: edk2-devel@lists.01.org
>Cc: Kinney, Michael D <michael.d.kin...@intel.com>; Heyi Guo 
><heyi....@linaro.org>; Tian, Feng <feng.t...@intel.com>;
>Zeng, Star <star.z...@intel.com>
>Subject: [edk2] [PATCH] MdeModulePkg/TerminalDxe: Set polling rate by serial 
>IO mode
>
>Calculate serial input polling rate according to parameters from
>serial IO mode as below, to fix potential input truncation.
>
>Polling interval (100ns) =
>FifoDepth * (StartBit + DataBits + StopBits + ParityBits) * 10,000,000
>/ BaudRate
>(StopBits is assumed to be 1 and ParityBits is ignored for simplicity.
>
>However, as the event is time sensitive, we need to align the interval
>to timer interrupt period to make sure the event will be triggered at
>the expected rate. E.g. if the interval is 2.7ms and timer interrupt
>period is 1ms, the event will be triggered by time slice sequence as
>below:
>3ms 3ms 2ms 3ms 3ms 2ms...
>
>In such case we will adjust the polling interval to be 2ms.

Heyi,
I remember we had a discussion about the polling interval calculation
equation a month ago. The equation used in the patch looks good to me.
Because the timer handler is called sometimes every 3ms but not 2.7ms
resulting the key loss?
Just want to confirm with you.


Regards,
Ray

>
>Contributed-under: TianoCore Contribution Agreement 1.0
>Signed-off-by: Heyi Guo <heyi....@linaro.org>
>Cc: Feng Tian <feng.t...@intel.com>
>Cc: Star Zeng <star.z...@intel.com>
>Cc: Michael D Kinney <michael.d.kin...@intel.com>
>---
> .../Universal/Console/TerminalDxe/Terminal.c       |  5 +-
> .../Universal/Console/TerminalDxe/Terminal.h       | 28 ++++++-
> .../Universal/Console/TerminalDxe/TerminalConIn.c  | 92 ++++++++++++++++++++++
> .../Universal/Console/TerminalDxe/TerminalDxe.inf  |  1 +
> 4 files changed, 123 insertions(+), 3 deletions(-)
>
>diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
>b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
>index 6fde3b2..2944707 100644
>--- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
>+++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
>@@ -71,6 +71,7 @@ TERMINAL_DEV  mTerminalDevTemplate = {
>   },
>   NULL, // TerminalConsoleModeData
>   0,  // SerialInTimeOut
>+  0,  // KeyboardTimerInterval
>
>   NULL, // RawFifo
>   NULL, // UnicodeFiFo
>@@ -984,10 +985,12 @@ TerminalDriverBindingStart (
>                     );
>     ASSERT_EFI_ERROR (Status);
>
>+    TerminalDevice->KeyboardTimerInterval = GetKeyboardTimerInterval (Mode);
>+
>     Status = gBS->SetTimer (
>                     TerminalDevice->TimerEvent,
>                     TimerPeriodic,
>-                    KEYBOARD_TIMER_INTERVAL
>+                    TerminalDevice->KeyboardTimerInterval
>                     );
>     ASSERT_EFI_ERROR (Status);
>
>diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h
>b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h
>index 269d2ae..a1ff595 100644
>--- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h
>+++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h
>@@ -28,6 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
>EXPRESS OR IMPLIED.
> #include <Protocol/DevicePath.h>
> #include <Protocol/SimpleTextIn.h>
> #include <Protocol/SimpleTextInEx.h>
>+#include <Protocol/Timer.h>
>
> #include <Library/DebugLib.h>
> #include <Library/UefiDriverEntryPoint.h>
>@@ -68,8 +69,6 @@ typedef struct {
>   UINTN   Rows;
> } TERMINAL_CONSOLE_MODE_DATA;
>
>-#define KEYBOARD_TIMER_INTERVAL         200000  // 0.02s
>-
> #define TERMINAL_DEV_SIGNATURE  SIGNATURE_32 ('t', 'm', 'n', 'l')
>
> #define TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('t', 'm', 'e', 
> 'n')
>@@ -91,6 +90,7 @@ typedef struct {
>   EFI_SIMPLE_TEXT_OUTPUT_MODE         SimpleTextOutputMode;
>   TERMINAL_CONSOLE_MODE_DATA          *TerminalConsoleModeData;
>   UINTN                               SerialInTimeOut;
>+  UINT64                              KeyboardTimerInterval;
>   RAW_DATA_FIFO                       *RawFiFo;
>   UNICODE_FIFO                        *UnicodeFiFo;
>   EFI_KEY_FIFO                        *EfiKeyFiFo;
>@@ -1358,4 +1358,28 @@ TerminalConInTimerHandler (
>   IN EFI_EVENT            Event,
>   IN VOID                 *Context
>   );
>+
>+/**
>+  Calculate input polling timer interval by serial IO mode.
>+
>+  @param  Mode                  Pointer to serial IO mode.
>+
>+  @retval The required polling timer interval in 100ns.
>+
>+**/
>+UINT64
>+GetKeyboardTimerInterval (
>+  IN EFI_SERIAL_IO_MODE   *Mode
>+  );
>+
>+/**
>+  Update period of polling timer event.
>+
>+  @param  TerminalDevice        The terminal device to update.
>+**/
>+VOID
>+UpdatePollingRate (
>+  IN TERMINAL_DEV         *TerminalDevice
>+  );
>+
> #endif
>diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
>b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
>index 3be877b..e7788a0 100644
>--- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
>+++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
>@@ -15,6 +15,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
>EXPRESS OR IMPLIED.
>
> #include "Terminal.h"
>
>+EFI_TIMER_ARCH_PROTOCOL *gTimer;
>
> /**
>   Reads the next keystroke from the input device. The WaitForKey Event can
>@@ -502,6 +503,94 @@ TerminalConInWaitForKey (
> }
>
> /**
>+  Calculate input polling timer interval by serial IO mode.
>+
>+  @param  Mode                  Pointer to serial IO mode.
>+
>+  @retval The required polling timer interval in 100ns.
>+
>+**/
>+UINT64
>+GetKeyboardTimerInterval (
>+  IN EFI_SERIAL_IO_MODE *Mode
>+  )
>+{
>+  UINT32                FifoDepth;
>+  UINT64                BaudRate;
>+  UINT64                Interval;
>+  UINT64                TimerPeriod;
>+  EFI_STATUS            Status;
>+
>+  // Make some assumption if the values are not suitable for calculating.
>+  BaudRate = Mode->BaudRate;
>+  if (BaudRate == 0) {
>+    BaudRate = 115200;
>+  }
>+  FifoDepth = Mode->ReceiveFifoDepth;
>+  if (FifoDepth == 0) {
>+    FifoDepth = 1;
>+  }
>+
>+  // We assume stop bits to be 1 and ignore parity bit to make it simple
>+  // and fast enough to poll.
>+  Interval = DivU64x64Remainder (
>+    FifoDepth * (1 + Mode->DataBits + 1) * 10000000,
>+    Mode->BaudRate,
>+    NULL
>+    ); 
>+
>+  // As this is a time sensitive event, we still need to align the
>+  // interval to timer interrupt period.
>+  if (gTimer == NULL) {
>+    Status = gBS->LocateProtocol (
>+        &gEfiTimerArchProtocolGuid,
>+        EFI_NATIVE_INTERFACE,
>+        (VOID **) &gTimer
>+        );
>+    ASSERT_EFI_ERROR (Status);
>+  }
>+
>+  Status = gTimer->GetTimerPeriod (gTimer, &TimerPeriod);
>+  ASSERT_EFI_ERROR (Status);
>+
>+  if (Interval <= TimerPeriod) {
>+    return TimerPeriod;
>+  }
>+  return MultU64x64 (DivU64x64Remainder (Interval, TimerPeriod, NULL), 
>TimerPeriod);
>+}
>+
>+
>+/**
>+  Update period of polling timer event.
>+
>+  @param  TerminalDevice        The terminal device to update.
>+**/
>+VOID
>+UpdatePollingRate (
>+  IN TERMINAL_DEV         *TerminalDevice
>+  )
>+{
>+  UINT64                  NewInterval;
>+  EFI_STATUS              Status;
>+
>+  NewInterval = GetKeyboardTimerInterval (TerminalDevice->SerialIo->Mode);
>+
>+  if (TerminalDevice->KeyboardTimerInterval == NewInterval) {
>+    return;
>+  }
>+
>+  Status = gBS->SetTimer (
>+                  TerminalDevice->TimerEvent,
>+                  TimerPeriodic,
>+                  NewInterval
>+                  );
>+  ASSERT_EFI_ERROR (Status);
>+
>+  TerminalDevice->KeyboardTimerInterval = NewInterval;
>+}
>+
>+
>+/**
>   Timer handler to poll the key from serial.
>
>   @param  Event                    Indicates the event that invoke this 
> function.
>@@ -560,6 +649,9 @@ TerminalConInTimerHandler (
>       TerminalDevice->SerialInTimeOut = SerialInTimeOut;
>     }
>   }
>+
>+  UpdatePollingRate (TerminalDevice);
>+
>   //
>   // Check whether serial buffer is empty.
>   // Skip the key transfer loop only if the SerialIo protocol instance
>diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
>b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
>index 0780296..dfd5035 100644
>--- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
>+++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
>@@ -84,6 +84,7 @@
>   gEfiSimpleTextInProtocolGuid                  ## BY_START
>   gEfiSimpleTextInputExProtocolGuid             ## BY_START
>   gEfiSimpleTextOutProtocolGuid                 ## BY_START
>+  gEfiTimerArchProtocolGuid                     ## CONSUMES
>
> [Pcd]
>   gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType           ## 
> SOMETIMES_CONSUMES
>--
>2.7.0
>
>_______________________________________________
>edk2-devel mailing list
>edk2-devel@lists.01.org
>https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to