From patchwork Sat Apr 23 08:53:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gary guo X-Patchwork-Id: 66516 Delivered-To: patch@linaro.org Received: by 10.140.93.198 with SMTP id d64csp83504qge; Sat, 23 Apr 2016 01:53:46 -0700 (PDT) X-Received: by 10.66.244.233 with SMTP id xj9mr34319942pac.19.1461401626633; Sat, 23 Apr 2016 01:53:46 -0700 (PDT) Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id le10si13008838pab.161.2016.04.23.01.53.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 23 Apr 2016 01:53:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) client-ip=198.145.21.10; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 8248F1A207E; Sat, 23 Apr 2016 01:53:45 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-io0-x22f.google.com (mail-io0-x22f.google.com [IPv6:2607:f8b0:4001:c06::22f]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 2BAE61A2065 for ; Sat, 23 Apr 2016 01:53:44 -0700 (PDT) Received: by mail-io0-x22f.google.com with SMTP id d62so44661655iof.2 for ; Sat, 23 Apr 2016 01:53:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=SVxXJ2hjahK5faY/p2/+jipDdl2WadZ2AIgsmYek8Nc=; b=UoFCCbJXhAT+756wRq8qzIXD9lffFJMWybPG+HE7TRAGJJY3tH7z+DEMEJePWxBJLP nuA+RADMcOW1gqwf1hVm351UtymfSj+tg+4ik7xpAfI5FS+K+gJcpMrUAID7n2xMMEtd wQURVzdSxUn4zrRJcj6pNQOsOOXhcUEyo1VbE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=SVxXJ2hjahK5faY/p2/+jipDdl2WadZ2AIgsmYek8Nc=; b=Hl0rvB15PrBngpffOUl4iC8cIR1evb+AYCgcWsRb3DBhZ0e5zYo6YZYPdZO9vgkUs8 7EdWr1J4siZvaxFUoho1DJPU6jiwmfsL0M8mPEEVHICsBDYt6dXwqiEQ9pIkMiiFSTEN 04cr9NJiJ7e2bgToUfPa/9Vd1BLdb89RKNwtPQuCgN1zH9rj55m7hxWpkOYZEK1jOPYE VI5LSi7uMHrKQb+N5h08U/ga0UTLRz32V3Dx98t0CiZSf1Eep0OEzxh1C52yFutn284R wEf3tYEfNvwdN5+4TXUy/Pnzxs03hfvOLTSKitiXTRKPTd9ZQGaj69mW0CF9Uv/KmoYF RSog== X-Gm-Message-State: AOPr4FU4dRLUlKXxK8DrXgj0C4iBCPdVvdWoFjtIJRquOK7JnP/iXzNP8q2y0D1kIUpWiqqZ X-Received: by 10.107.29.132 with SMTP id d126mr28586133iod.14.1461401623481; Sat, 23 Apr 2016 01:53:43 -0700 (PDT) Received: from localhost.localdomain ([104.238.45.87]) by smtp.gmail.com with ESMTPSA id ke5sm3623843igb.17.2016.04.23.01.53.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 23 Apr 2016 01:53:42 -0700 (PDT) From: Heyi Guo To: edk2-devel@lists.01.org Date: Sat, 23 Apr 2016 16:53:30 +0800 Message-Id: <1461401610-20118-1-git-send-email-heyi.guo@linaro.org> X-Mailer: git-send-email 2.7.0 Subject: [edk2] [PATCH] MdeModulePkg/TerminalDxe: Set polling rate by serial IO mode X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Michael D Kinney , Heyi Guo , Feng Tian , Star Zeng MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" 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. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Heyi Guo Cc: Feng Tian Cc: Star Zeng Cc: Michael D Kinney --- .../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(-) -- 2.7.0 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel 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 #include #include +#include #include #include @@ -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