> On Apr 27, 2016, at 8:10 PM, Ni, Ruiyu <ruiyu...@intel.com> wrote:
> 
>> 
>> -----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.
> 

Is it safe to make assumptions based on an implementation of an AP? Other 
platforms could be using different code?

Thanks,

Andrew Fish

> 
> 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

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to