From patchwork Wed Mar 16 10:57:56 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gary guo X-Patchwork-Id: 63918 Delivered-To: patch@linaro.org Received: by 10.112.199.169 with SMTP id jl9csp1241283lbc; Wed, 16 Mar 2016 03:58:36 -0700 (PDT) X-Received: by 10.98.66.90 with SMTP id p87mr4793421pfa.78.1458125913681; Wed, 16 Mar 2016 03:58:33 -0700 (PDT) Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id fl1si4612058pad.15.2016.03.16.03.58.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Mar 2016 03:58:33 -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; 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; dkim=neutral (body hash did not verify) header.i=@linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 751161A1FA0; Wed, 16 Mar 2016 03:58:52 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-pf0-x22f.google.com (mail-pf0-x22f.google.com [IPv6:2607:f8b0:400e:c00::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 024761A1F97 for ; Wed, 16 Mar 2016 03:58:51 -0700 (PDT) Received: by mail-pf0-x22f.google.com with SMTP id u190so70895567pfb.3 for ; Wed, 16 Mar 2016 03:58:31 -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:in-reply-to:references; bh=xRuU/49FCPPNpiLgJZdZVLtkDiJFkdqNt4bnoALh1oA=; b=I9GL0Nzyhd8kGiHut2sFwK19fueqcsU0O/phKJYcnhNG8GV69U7YBrVPqU/DuRwLkW pVJE57DDZpyiCpm56on9WIehkKYKlLuQQA0d4baALgkGkcS16FC7RTfSbyPIn1hDUoqI 4sEIvujtkCcWcNPnuFys/1BdPwohoqSlJr2f8= 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:in-reply-to :references; bh=xRuU/49FCPPNpiLgJZdZVLtkDiJFkdqNt4bnoALh1oA=; b=eIXkTbDmFLbxmp5G0kyUyTDc+oEjIqJYyl30sX6zw2Lahb6VzPWSa0VPSerK49qv6J S5AsBrsfG4eU9reCIDmqMwnU6iHgnI+ysIZQLjHfkifRlZftz8KC+FiBxgD4s82F+SNg 9TN2zHh7pKIx/UNg9RnmFuLDVDLIVguzNSLxiQ5+rQ+oIO9cKmxQDGKccX+QqT/9LfnU K51vAxUIg4dtBt1tm7PPdA37tT5EiaA+XS5gsVSCaa34+fTnNOXzEse8tQ2cUyivV9Og 0UBiSVif0i5vYTOiTHBO0TJ5qcSJXay+R8TcnG1lE0rI//z1+HNie3uFF5w0H2DwE5H2 0rIA== X-Gm-Message-State: AD7BkJLYNM/qlzYt8V6y6RfRjpNkQFdnyIBV+VzFhxbSUwg2LTK8NRVOFqwI845TuYHchNiq X-Received: by 10.66.139.234 with SMTP id rb10mr4810915pab.104.1458125911541; Wed, 16 Mar 2016 03:58:31 -0700 (PDT) Received: from localhost.localdomain ([104.237.91.144]) by smtp.gmail.com with ESMTPSA id s66sm4721896pfi.3.2016.03.16.03.58.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 16 Mar 2016 03:58:31 -0700 (PDT) From: Heyi Guo To: edk2-devel@lists.01.org Date: Wed, 16 Mar 2016 18:57:56 +0800 Message-Id: <1458125876-8097-3-git-send-email-heyi.guo@linaro.org> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1458125876-8097-1-git-send-email-heyi.guo@linaro.org> References: <1458125876-8097-1-git-send-email-heyi.guo@linaro.org> Cc: Heyi Guo , Feng Tian , Star Zeng Subject: [edk2] [RFC 3/3] MdeModulePkg/TerminalDxe: Set polling rate by serial IO mode X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , 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 with fixed polling interval 0.02s. Polling interval (100ns) = FifoDepth * (ParityBits + StopBits + DataBits) * 10,000,000 / BaudRate However, as UEFI events will probably delayed by other code of higher TPL, we use below equation to make polling rate fast enough: FifoDepth * DataBits * 10,000,000 * 2 / (BaudRate * 3) Signed-off-by: Heyi Guo Cc: Feng Tian Cc: Star Zeng --- .../Universal/Console/TerminalDxe/Terminal.c | 5 +- .../Universal/Console/TerminalDxe/Terminal.h | 27 ++++++++- .../Universal/Console/TerminalDxe/TerminalConIn.c | 68 ++++++++++++++++++++++ 3 files changed, 98 insertions(+), 2 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 5adaa97..db790f3 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 + DEFAULT_KEYBOARD_TIMER_INTERVAL, // 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..58d5664 100644 --- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h +++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h @@ -68,7 +68,7 @@ typedef struct { UINTN Rows; } TERMINAL_CONSOLE_MODE_DATA; -#define KEYBOARD_TIMER_INTERVAL 200000 // 0.02s +#define DEFAULT_KEYBOARD_TIMER_INTERVAL 200000 // 0.02s #define TERMINAL_DEV_SIGNATURE SIGNATURE_32 ('t', 'm', 'n', 'l') @@ -91,6 +91,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 +1359,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 2215df6..22349a0 100644 --- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c +++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c @@ -502,6 +502,71 @@ 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; + + if (Mode->BaudRate == 0) { + return DEFAULT_KEYBOARD_TIMER_INTERVAL; + } + + FifoDepth = Mode->ReceiveFifoDepth; + // Fix incorrect FIFO depth + if (FifoDepth == 0) { + FifoDepth = 1; + } + + // We ignore stop bits and parity bit, and reduce the interval by 1/3, + // to make polling rate fast enough to avoid serial input truncation. + return DivU64x64Remainder ( + FifoDepth * Mode->DataBits * 10000000 * 2, + Mode->BaudRate * 3, + NULL + ); +} + + +/** + 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 +625,9 @@ TerminalConInTimerHandler ( TerminalDevice->SerialInTimeOut = SerialInTimeOut; } } + + UpdatePollingRate (TerminalDevice); + // // Check whether serial buffer is empty. // Skip the key transfer loop only if the SerialIo protocol instance