> 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